数据结构学习二 数据结构之链表代码版【创建,遍历,删除,插入】
2016-07-29 22:35
435 查看
代码:
/******动态链表的建立、删除、插入的完整程序*****/ #include "stdio.h" #include "string.h" #include "stdlib.h" #define Len sizeof(struct student) //定义一个结构体等长的常量len,用于给新的结构体分配空间 /********************************* 结构体名:student **********************************/ struct student { int num; int score; struct student *next; };//此分号容易忘记!!! struct student *head,*p1,*p2;//P1指向待插入节点,P2为首节点,head为头结点! int n=0; //用于记录插入链表的个数 /********************************* 函数名 :*creat() 参数 :无 功能 :用于插入新的链表 返回值 :返回链表的首地址 head 基本思路: 三个结点(头结点head、尾结点 NULL 和待插入结点 P) 第一步:定义头结点head、尾结点 p2 和待插入结点p1,待插入的结点数据部分初始化; 第二步:P1该结点被头结点、尾结点同时指向。 P1=p2=(struct student*)malloc(LEN);头指针部分为空,head=NULL; 第三步:重复申请待插入结点空间,对该结点的数据部分赋值(或输入值),将该结点插入在最前面,或者最后面(书上在尾部插入). P2->next=P1; P2=P1; 第四步:最后:P2->next=NULL; *********************************/ struct student *creat() { //第二步 P1该结点被头结点、尾结点同时指向。P1=p2=(struct student*)malloc(LEN);头指针部分为空,head=NULL; head=NULL; p1=(struct student*)malloc(Len); //插入前先开辟一个空节点位置,给新的节点分配空间 p2=p1;//P1替换掉P2,包括指针域和数据域 //第一步 定义头结点head、尾结点 p2 和待插入结点p1,待插入的结点数据部分初始化; puts("请输入学生号和成绩"); scanf("%d %d",&(p1->num),&(p1->score)); while(p1->num!=0) { n++; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct student*)malloc(Len); printf("建立链表%d\n",n); scanf("%d %d",&(p1->num),&(p1->score)); } p2->next=NULL; puts("链表建立结束"); return head; } /******************************************* 函数名 :print() 参数 :结构体的首地址 *head1 功能 :输出链表 返回值 : 无 基本思路:传入一个链表的头结点地址,遍历链表即可。 1.单向链表总是从头结点开始的; 2.每访问一个结点,就将当前指针向该结点的下一个结点移动: p=p->next; 3.直至下一结点为空 P=NULL *******************************************/ void print(struct student *head1) { struct student *p3; p3=head1; puts("输出链表"); puts("学号 成绩"); while(p3!=NULL) { printf("%d %d\n",p3->num,p3->score); p3=p3->next; } } /******************************************* 函数名 :*del() 参数 :链表首地址 *head 以及要删除的学习 学号 功能 :把指定学号的学生信息从链表中 删除掉, 返回值 :返回链表的首地址head 基本思路:两种情况: 1、要删的结点是头指针所指的结点则直接操作; 2、不是头结点,要依次往下找。另外要考虑:空表和找不到要删除的结点 ********************************************/ struct student *del(struct student *head ,int num) { struct student *sp1,*sp2; if(head==NULL) {printf("list is null!"); goto End;} sp1=head; while(num!=sp1->num) //删除的不是所要找的结点 { sp2=sp1;sp1=sp1->next; //当节点中的学号不想等时移动指针sp1 } if(num==sp1->num) { if(sp1==head) { head=sp1->next; //若sp1指向的是首结点,把第二个结点地址给head } else if(sp1->next==NULL) /*若sp1指向的最后一个结点,把倒数第二个 sp2->next=NULL作为最后一个结点*/ { sp2->next=NULL; } else { sp2->next=sp1->next; //否则删除sp1所指的结点 } n--; printf("已删除%d",num); } else printf("找不到该节点\n"); End :; return head; } /******************************************** 函数名 :*insert() 参数 :链表首地址*head 和要插入新结点 地址*newstu 功能 :在链表中再插入新的结点 返回值 :返回新的链表首地址head 基本思路:将一个结点插入到已有的链表中 插入原则: 1、插入操作不应破坏原链接关系 2、插入的结点应该在它该在的位置 实现方法: 应该有一个插入位置的查找子过程 共有三种情况: 1、插入的结最小 2、插入的结点最大 3、插入的结在中间 同删除一样,需要几个临时指针: P0: 指向待插的结点;初始化:p0=数组stu; P1: 指向要在P1之前插入结点;初始化: p1=head; P2: 指向要在P2之后插入结点; 插入操作:当符合以下条件时:p0->num 与 p1->num 比较找位置 if(p0->num>p1->num)&&(p1->next!=NULL) 则插入的结点不在p1所指结点之前;指针后移,交给p2; p1= p1->next; p2=p1; 则继续与p0指向的数组去比,直到(p1->next!=NULL)为止。 否则有两种情况发生: if(head==p1) head=p0;p0->next=p1插到原来第一个结点之前; else p2->next=p0;p0->next=p1; 插到 p2 指向的结点之后; 还有另外一种情况:插到最后的结点之后; p1->next=p0;p0->next=NULL; *********************************************/ struct student *insert(struct student *head, struct student *newstu) { struct student *p0,*sp1,*sp2; sp1=head; //使sp1指向第一个结点 p0=newstu; //使p0指向新结点的地址 if(head==NULL) //原来的链表是空的 { head=p0; p0->next=NULL; } else { while(sp1->num<p0->num&&sp1->next!=NULL) { sp2=sp1; //使sp2指向刚才sp1的结点,移动sp1指针到下一个结点 sp1=sp1->next; } if(p0->num<sp1->num) { if(head==sp1) { head=p0; //插入到原来第一个结点之前 p0->next=sp1; //让新的结点指向第一个结点 } else { sp2->next=p0; //否则插入到sp2和sp1之间 p0->next=sp1; } } n++; } return head; //返回新的首地址; } void main() { struct student *p,newstu; int num; puts("创建链表"); p=creat(); //创建链表 print(p); //输出全部链表 puts("请输入要删除的学号"); scanf("%d",&num); p=del(p,num); // 删除链表 print(p); puts("请输入插入学生的学号和成绩"); scanf("%d %d",&newstu.num,&newstu.score); p=insert(p,&newstu); //插入链表 print(p); print(p); free(p1); free(p2); free(head); }
相关文章推荐
- 数据结构学习二 数据结构之链表图解版【创建,遍历,删除,插入】
- 数据结构—链表的定义、创建、遍历、插入、删除
- 数据结构链表创建,遍历,是否为空,求长度,插入,删除算法的演示
- 很简单的数据结构:链表线性存储的创建、取数据、数据添加、数据插入、数据删除
- 用结构体实现链表的创建、遍历、结点插入、结点删除、链表删除-----带菜单选项
- c++实现单链表创建,删除,遍历,插入,修改操作
- 数据结构学习(五)——循环双链表的操作之创建,插入、删除
- malloc的链表,创建链表,遍历链表,插入节点,删除节点
- 单向循环链表创建、遍历、插入、删除、查找(按位置,按元素值)、清空、销毁
- 链表的一系列操作(创建,插入,删除,从前到后,从后到前遍历整个链表)
- 单向链表的创建、遍历、求长、判存、判空、插入、删除、查找(按位置或元素)、合并
- 学习笔记——C语言实现单链表的基本操作:创建、输出、插入结点、删除结点、逆序链表
- 数据结构-链表创建,删除,插入,反转,连接
- 链表的创建、遍历、节点的插入、节点的删除
- 数据结构之链表(一)创建,插入,删除
- 数据结构顺序表的操作全集(创建,遍历,插入,删除,排序等等)
- 数据结构 图 创建 插入 遍历 删除 销毁
- 算法学习-数据结构之链表操作,创建,插入,删除,查找。
- C语言中,链表的创建,插入,删除,遍历,求链表长度,排序等
- 学习笔记——C语言实现单链表的基本操作:创建、输出、插入结点、删除结点、逆序链表