设为首页 加入收藏

TOP

C语言 链表的创建,以及节点的增加和删除(一)
2017-06-23 10:22:22 】 浏览:523
Tags:语言 创建 以及 节点 增加 删除

第一次写博客,如有错误还请指正…………
今天下午倒腾了一下c语言的链表,感觉链表就是一个小型的数据库,用于简单的小程序的用户信息存储和管理还是很方便的。
下面为方便起见,以学生信息为例:
链表采用了动态分配的办法为一个结构分配内存空间。每一次分配一块空间可用来存放一个学生的数据,我们可称之为一个结点。有多少个学生就应该申请分配多少块内存空间,也就是说要建立多少个结点。当然用结构数组也可以完成上述工作,但如果预先不能准确把握学生人数,也就无法确定数组大小。而且当学生留级、退学之后也不能把该元素占用的空间从数组中释放出来。用动态存储的方法可以很好地解决这些问题。有一个学生就分配一个结点,无须预先确定学生的准确人数,某学生退学,可删去该结点,并释放该结点占用的存储空间。从而节约了宝贵的内存资源。另一方面,用数组的方法必须占用一块连续的内存区域。而使用动态分配时,每个结点之间可以是不连续的(结点内是连续的)。结点之间的联系可以用指针实现。 即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域。
可在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域可赋为0。这样一种连接方式,在数据结构中称为“链表”。
下面给出一个简单的例子,包含链表的创建,

#include
  
   
#include
   
     #define LEN sizeof (struct stu) /* head为(伪)头指针,pbefore为指向两相邻结点的前一结点的指针变量。pafter为后一结点的指针变量。 */ //定义学生个数 int n=4; //定义链表结构体 typedef struct stu{ int num; int age; struct stu *next; }TYPE; /*定义删除函数:删除所选中的节点*/ void delete(TYPE *head,int number) { int i; TYPE *list=head; TYPE *tp=NULL; //这里循环n+1次,是因为包含头节点在内总共有n+1个节点 for(i=0;i<(n+1);i++){ printf("the next:%ld\n",(long)list->next); if(list->num==number){ if(list->next==0){ tp->next=0; break; }else{ tp->next=list->next; break; } } tp=list;// 临时指针指向的是前一节点 list=list->next; //继续判断下一节点 } } /*定义查询函数:显示链表中所有信息*/ void query(TYPE *head) { TYPE *list=head; while(list) { printf("%d,%d\n",list->num,list->age); printf("the next:%ld\n",(long)list->next); list=list->next; } } int main() { //这是定义的真正的头节点 struct stu *head; head->num=0; head->age=0; struct stu *thead,*pbefore,*pafter; int i; for(i=0;i
    
     num,&pafter->age); if(i==0) pbefore=thead=pafter; //第一次循环,直接设置头节点 else pbefore->next=pafter; //这里的pbefore其实是上一轮循环的after赋予的,所以是 “前一个节点” //注意:这里改动的不是pbefore,而是pbefore指向的内存里的数据 pafter->next=NULL; // 将最后的指针域清零,赋给pbefore,即前节点 pbefore=pafter;// 这里pbefore指向了新的内存,也就是下一个节点 // 强调一下,pbefore只是一个指针 } head->next=thead; query(head); int number; printf("you want to delete:"); scanf("%d",&number); delete(head,number); query(head); return 0; }
    
   
  

以上程序包含了一个节点数为n+1的链表(n个学生节点和1个头节点,因为头节点没有数据域)。如果没有提前定义头节点,则第一个学生的节点则为头节点,这样就导致这个头节点无法删除。这里写图片描述
上图可以看出,如果直接删除了头节点,会发生段错误。

现在我们在链表的尾部增加一个节点

#include
  
   
#include
   
     #define LEN sizeof (struct stu) typedef struct stu{ int num; int age; struct stu *next; }TYPE; int n=4; /*增加节点函数:返回新的尾部节点地址*/ TYPE *add(TYPE* tail) { TYPE *new; new=(TYPE*) malloc(LEN); printf("input the new num and age\n"); scanf("%d%d",&new->num,&new->age); tail->next=new; printf("tail:%ld",(long)tail); new->next=NULL;//缺了这一句,新的节点数据就显示不出了 tail=new; printf("new tail:%ld",(long)tail); return tail; } /*删除节点函数*/ void delete(TYPE *head,TYPE* tail,int number) { int i; TYPE *list=head; TYPE *tp=NULL; for(i=0;i<(n+1);i++){ // printf("the next:%ld\n",(long)list->next); if(list->num==number){ if(list->next==0){ tp->next=0; tail=tp;//若尾部节点被删除,则更新尾部节点 break; }else{ tp->next=list->next; break; } } tp=list;// 临时指针指向的是前一节点 list=list->next; //继续判断下一节点 } } /*查询函数:显示所有节点数据*/ void query(TYPE *head) { TYPE *list=head; while(list) { printf("%d,%d\n",list->num,list->age); //printf("the next:%ld\n",(long)list->next); list=list-
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言学习第一天 下一篇求鞍点

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目