单链表的实现分为两种单链表(其实差别并不是很大):带头结点和不带头结点,分别对应下面图中的上下两种。

链表的每一个结点是由两个域组成:数据域和指针域,分别存放所含数据和下一个结点的地址(这都是很明白的东西)

图中的东西可以分为三种:头指针llist;头节点info;正常的节点ki

下面定义结点的类型和单链表的类型:

struct Node;
typedef struct Node * PNode;
struct Node{
DataType info;
PNode link;
};
typedef struct Node * LinkList;
//很明显我们定义的结点指针类型和单链表的类型实际上是一样的东西
//后续的代码暂时与书上的内容保持一致,均使用有头结点的链表
//总结过后再将不带头结点的单链表实现补上

创建一个空链表:

LinkList creatNullList_link(void){
LinkList llist = (LinkList)malloc(sizeof(struct Node));  //创建一个指向Node类型的指针llist
if(llist != NULL) llist->link = NULL;  //将其指向为空,也就是链表末尾
else printf("OUTOFSPACE!");
return llist; //看上面的代码后可知,llist可能为空,所以后面其他的函数经常会先判断了llist的情况
}

是否是空链表:

int isNullList_link(LinkList llist){
return (llist->link == NULL);
}
//判断链表是否为空的代码比较简单

在链表中求第一个值为x的结点的存储位置:

PNode locate_link(LinkList llist,DataType x){
PNode p;
if (llist == NULL) return NULL;  
p = llist->link;
while(p != NULL && p->info != x) p = p->link;
return p;
}
//为什么要判断llist是否为空而不是判断llist->link是否为空?
//如果llist为空,那使用llist->link不就是对一个空指针操作了吗,记得学指针的时候书上的一句话嘛,千万不要用没有初始化的指针,这里如果其指向为空,那llist->link也就不知道指向哪里

在p结点的后面插入一个值为x的新结点,返回是否插入成功的标志:

int insertPost_link(LinkList llist,PNode p,DataType x){
  PNode q = (PNode)malloc(sizeof(struct Node));
  if (q == NULL){
    printf("OUTOFSPACE");
    return 0;
  } 
  q->info = x;
  q->link = p->link;
  p->link = q;
  return 1;
}//下图为操作顺序,操作顺序不能反
//这一个方法是不需要用到llist

在p结点的前面插入值为x的新结点,返回插入成功与否的标志:

int insertPre_link(LinkList llist,PNode p,DataType x){
  PNode r;
  PNode q = (PNode)malloc(sizeof(struct Node));
  if(q == NUll){
    printf("OUTOFSPACE");
    return 0;
  }
  r = locatePre_link(llist,p);
  q->info = x;
  q->link = r->link;
  r->link = q;
  reutrn 1;
}
//找p结点的前驱结点
PNode locatePre_link(LinkList llist,PNode p){
  PNode p1;
  if (llist == NULL)  return NULL;
  p1 = llist;
  while(p1->link!=NULL && p1->link==p){
    p1 = p1->link;
  }
  reutn p1;
}
//感觉这个难一点的就是前驱结点的查找,p1->link!=NULL && p1->link == p是这个找前驱结点的灵魂

删除第一个元素内容为x的结点,返回删除成功与否的标志:

int deleteV_link(LinkList llist,DataType x){
  //不展示的方法:前面有一个定位方法,找到元素x的结点p,然后前面还有一个找前驱结点的方法,然后就可以执行删除操作了
  //下面是书上的方法
  PNode q,p;
  p = llist;
  if (p == NULL)  return 0;
  while(p->link!=NULL && p->link->info==x) p = p->link;
  //p是要删除结点的前驱结点
  if (p->link == NULL){
    printf("NOT EXIST!");
    return 0;
  }
  else{
    q = p->link;
    p->link = q->link;
    //也可以是p->link = p->link->link
    free(q);
    return 1;
  }
}

目前这基本上是书本上的代码示例了,后续会补充未给出的思考题,并且给出没有头结点时上述函数方法。

  • 添加到短语集

     
    • 没有此单词集:中文(简体) -> 英语...

       
    • 创建新的单词集...
  • 拷贝
  • 添加到短语集

     
    • 没有此单词集:中文(简体) -> 英语...

       
    • 创建新的单词集...
  • 拷贝
  • 添加到短语集

     
    • 没有此单词集:中文(简体) -> 英语...

       
    • 创建新的单词集...
  • 拷贝
  • 添加到短语集

     
    • 没有此单词集:中文(简体) -> 英语...

       
    • 创建新的单词集...
  • 拷贝
  • 添加到短语集

     
    • 没有此单词集:中文(简体) -> 英语...

       
    • 创建新的单词集...
  • 拷贝
  • 添加到短语集

     
    • 没有此单词集:中文(简体) -> 英语...

       
    • 创建新的单词集...
  • 拷贝

最新文章

  1. 实时事件统计项目:优化flume:用file channel代替mem channel
  2. 一个前端引用Facebook评论插件案例
  3. 。tar.gz(bz或bz2等)安装
  4. 实现android手机来电拦截系统页面弹出自定义页面特效
  5. 网站建设中前端常用的jQuery+easing缓动的动画
  6. PHP将在对象被销毁前调用这个函数.它称为析构函数
  7. weka特征选择(IG、chi-square)
  8. 学习笔记day6:CSS3动画属性
  9. jquery 和 $
  10. wamp修改多站点配置
  11. cocos2d-x lua 使用http(下载图片, POST JSON)
  12. 通过js根据后台数据动态生成一个页面
  13. sass进阶篇总结一
  14. 4 weekend110的YARN的通用性意义 + yarn的job提交流程
  15. DllImport中的EntryPoint
  16. 《Linux命令行与shell脚本编程大全》第二十五章 创建与数据库、web及电子邮件相关的脚本
  17. python(leetcode)-重复元素算法题
  18. ubuntu 14.04 安装 eclipse
  19. 模板】AC自动机(简单版)
  20. TCP协议 连接三次握手

热门文章

  1. 《Effective Python》笔记——第2章 函数
  2. LeetCode随缘刷题之Java经典面试题将一个字符串数组进行分组输出,每组中的字符串都由相同的字符组成
  3. Redis 在 vivo 推送平台的应用与优化实践
  4. 10、架构--keepalive、四层负载均衡
  5. 4、Linux基础--系统目录
  6. rsync 与 inotify 的使用 & 实现实时同步备份
  7. Java架构师必备技能:docker使用大全
  8. python爬虫:爬虫的简单介绍及requests模块的简单使用
  9. [VM trunk ports]opensatck VM 单网卡,多VLAN配置
  10. Python 中线程和进程