当前位置:文档之家› 双向链表实验报告

双向链表实验报告

13软工转本1 钱剑滨实验报告双向链表实验报告信息工程系 13软工转本1 日期 2016年03月12日姓名钱剑滨学号 13131116 电话一、实验内容编写关于双向链表操作的C语言程序,要求包含双向链表的创建(生成)、输出(遍历)、查找、任意位置插入、有顺序插入、删除、等。

二、实验步骤1.分析操作所需思路,熟练运用单链表的各种特点。

2.编写程序,利用函数特性进行操作。

3.运行程序,纠正错误,对预测结果进行验证。

4.分析总结单链表的优缺点,并可以做到熟练掌握双向链表的各种操作。

三、设计概要1.本实验包含了7个函数:a)主函数main()b)创建链表函数Listcreate()c)数据输出函数Listprint()d)查找数据函数Listlocate()e)无序插入函数Listinsert_discretion ()f)有序插入函数Listinsert_orderg)删除数据函数Listdelete()2.明确函数的功能;a)Listcreate() 创建一个可控长度的斐波那契数列的双向链表。

b)Listprint() 将此链表中的数据全部输出。

c)Listlocate() 查找此链表中任意位置元素的值。

d)Listinsert_discretion ()向此链表的某个位置插入一组数据。

e)Listinsert_order() 向数列中插入一个数,使插入后的数列任然有序f)Listdelete() 将此链表的某个位置的一组数据删除。

四、程序设计1.函数前包含的头文件名、结点类型定义、全局变量和函数声明#include <stdio.h>#include <malloc.h>typedef struct number //定义结构体{struct number *prior;int num;struct number *next;}number;number *head; //定义全局变量头节点int k = 0; //k记录元素个数,防止溢出/*函数声明*/void Listcreate(); //建立链表void Listprint(); //全体输出void Listlocate(); //查找void Listinsert_discretion(); //任意位置插入void Listinsert_order(); //有顺序插入void Listdelete(); //删除2.主函数main()void main(){int select;printf("1、输入斐波那契数列的个数\n");printf("2、全部输出数列\n");printf("3、查找定位数列的元素\n");printf("4、添加数列元素\n");printf("5、插入顺序数列元素\n");printf("6、删除数列元素\n");printf("-------------------------------------\n");while (1){printf("请选择序号\n");scanf("%d", &select);switch (select){case 1: Listcreate(); break; //链表创建case 2: Listprint(); break; //全链表输出case 3: Listlocate(); break; //元素查找case 4: Listinsert_discretion(); break; //任意位置插入case 5: Listinsert_order(); break; //有顺序插入case 6: Listdelete(); break; //删除default: break;}}}3.创建链表函数Listcreate()void Listcreate() //建立链表{head = (number *)malloc(sizeof (number)); //开辟一个大小为number的内存空间给头节点head->next = NULL;head->prior = NULL;int a = 1,b = 1; //a、b为斐波那契数列的前两个元素int i;number *q;number *p = head; //p始终指向最后一个节点printf("输入元素的长度\n");scanf("%d",&i);/*给第一个元素赋值*/q = (number *)malloc(sizeof (number)); //开辟一个大小为number的内存空间给后面节点q->num = a;q->next = NULL; //新开辟的节点指向NULLp->next = q; //前一节点指向新开辟的节点q->prior = p; //开辟的节点前驱指向pp = p->next; //p指向新节点i = i - 1;k = k + 1;/*给第二个元素赋值*/q = (number *)malloc(sizeof (number));q->num = b;q->next = NULL;p->next = q;q->prior = p;p = p->next;i = i - 1;k = k + 1;/*给后续元素赋值*/while (i--)q = (number *)malloc(sizeof (number));q->num = (a+b);q->next = NULL;p->next = q;q->prior = p;p = p->next;a = a +b + b; //b = a - b; //将a+b的值付给b;b的值付给aa = a - b; //k = k + 1;}printf("链表建立成功\n");}4.数据输出函数Listprint()void Listprint() //全体输出{number *p = head->next;while (p != NULL){printf("%d ", p->num);p = p->next;}printf("\n");}5.查找数据函数Listlocate()void Listlocate() //查找{int i;number *p = head;printf("输入您要查询的元素位置\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("查询的位置不存在\n");}else{while (i--){p = p->next;}printf("所查找数为%d\n", p->num);}}6.无序插入函数Listinsert_discretion()void Listinsert_discretion() //任意位置插入{int i;number *q;number *p = head;printf("输入您要插入哪个元素的后面\n");scanf("%d", &i);if ((i > k) || (i < 0)){printf("插入的位置不存在\n");}else{while (i--){p = p->next; //p最后指向要插入位置的前一个节点}q = (number *)malloc(sizeof (number));if (p->next == NULL) //插到末尾{q->next = NULL; //B的下一个元素指向空p->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}else{q->next = p->next; //B的下一个元素指向p的下一个(两个不能反)p->next->prior = q; //p的下一个元素的前驱指向Bp->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}printf("输入您要插入的数\n");scanf("%d", &(q->num));k = k + 1;}printf("插入成功\n");}7.有序插入函数Listinsert_order ()void Listinsert_order() //有顺序插入{number *q;number *p = head;q = (number *)malloc(sizeof (number));printf("输入您要插入哪个数\n");scanf("%d", &q->num);while (p->next){if (p->next->num >= q->num) //插在第一个比数大或等于的的数前{q->next = p->next;p->next->prior = q;p->next = q;q->prior = p;k = k + 1;break;}else{p = p->next;}}if (p->next == NULL) //插到末尾{q->next = NULL;p->next = q;q->prior = p;k = k + 1;}printf("插入成功\n");}8.删除数据函数Listdelete ()void Listdelete() //删除{int i;number *q;number *p=head;printf("输入您要删除哪个元素\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("删除的位置不存在\n");}else{while (--i) //这里是先减再判断{p = p->next; //p指向被删除的元素的前一个元素}q = p->next; //q指向被删除的元素if (q->next == NULL) //删除最后一个元素{p->next = NULL;}else{p->next = q->next; //p的下一个元素指向q的下一个,即跳过被删除元素q->next->prior = p; //q的下一个元素的前驱指向p,也跳过被删除的元素}free(q); //清空删除元素k = k - 1;}printf("删除成功\n");}五、程序源码#include <stdio.h>#include <malloc.h>typedef struct number{struct number *prior;int num;struct number *next;}number;number *head; //定义全局变量头节点int k = 0; //k记录元素个数,防止溢出void Listcreate(); //建立链表void Listprint(); //全体输出void Listlocate(); //查找void Listinsert_discretion(); //任意位置插入void Listinsert_order(); //有顺序插入void Listdelete(); //删除void main(){int select;printf("1、输入斐波那契数列的个数\n");printf("2、全部输出数列\n");printf("3、查找定位数列的元素\n");printf("4、添加数列元素\n");printf("5、插入顺序数列元素\n");printf("6、删除数列元素\n");printf("-------------------------------------\n");while (1){printf("请选择序号\n");scanf("%d", &select);switch (select){case 1: Listcreate(); break;//链表创建case 2: Listprint(); break;//全链表输出case 3: Listlocate(); break; //元素查找case 4: Listinsert_discretion(); break; //任意位置插入case 5: Listinsert_order(); break; //有顺序插入case 6: Listdelete(); break; //删除default: break;}}}void Listcreate() //建立链表{head = (number *)malloc(sizeof (number)); //开辟一个大小为number 的内存空间给头节点head->next = NULL;head->prior = NULL;int a = 1,b = 1; //a、b为斐波那契数列的前两个元素int i;number *q;number *p = head; //p始终指向最后一个节点printf("输入元素的长度\n");scanf("%d",&i);q = (number *)malloc(sizeof (number)); //开辟一个大小为number的内存空间给后面节点q->num = a;q->next = NULL; //新开辟的节点指向NULLp->next = q; //前一节点指向新开辟的节点q->prior = p; //开辟的节点前驱指向pp = p->next; //p指向新节点i = i - 1;k = k + 1;q = (number *)malloc(sizeof (number));q->num = b;q->next = NULL;p->next = q;q->prior = p;p = p->next;i = i - 1;k = k + 1;while (i--){q = (number *)malloc(sizeof (number));q->num = (a+b);q->next = NULL;p->next = q;q->prior = p;p = p->next;a = a +b + b; //b = a - b; //将a+b的值付给b;b的值付给aa = a - b; //k = k + 1;}printf("链表建立成功\n");}void Listprint() //全体输出{number *p = head->next;while (p != NULL){printf("%d ", p->num);p = p->next;}printf("\n");}void Listlocate() //查找{int i;number *p = head;printf("输入您要查询的元素位置\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("查询的位置不存在\n");}else{while (i--){p = p->next;}printf("所查找数为%d\n", p->num);}}void Listinsert_discretion() //任意位置插入{int i;number *q;number *p = head;printf("输入您要插入哪个元素的后面\n");scanf("%d", &i);if ((i > k) || (i < 0)){printf("插入的位置不存在\n");}else{while (i--){p = p->next; //p最后指向要插入位置的前一个节点}q = (number *)malloc(sizeof (number));if (p->next == NULL) //插到末尾{q->next = NULL; //B的下一个元素指向空p->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}else{q->next = p->next; //B的下一个元素指向p的下一个(两个不能反)p->next->prior = q; //p的下一个元素的前驱指向Bp->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}printf("输入您要插入的数\n");scanf("%d", &(q->num));k = k + 1;}printf("插入成功\n");}void Listinsert_order() //有顺序插入{number *q;number *p = head;q = (number *)malloc(sizeof (number));printf("输入您要插入哪个数\n");scanf("%d", &q->num);while (p->next){if (p->next->num >= q->num) //插在第一个比数大或等于的的数前{q->next = p->next;p->next->prior = q;p->next = q;q->prior = p;k = k + 1;break;}else{p = p->next;}}if (p->next == NULL) //插到末尾{q->next = NULL;p->next = q;q->prior = p;k = k + 1;}printf("插入成功\n");}void Listdelete() //删除{int i;number *q;number *p=head;printf("输入您要删除哪个元素\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("删除的位置不存在\n");}else{while (--i) //这里是先减再判断{p = p->next; //p指向被删除的元素的前一个元素}q = p->next; //q指向被删除的元素if (q->next == NULL) //删除最后一个元素{p->next = NULL;}else{p->next = q->next; //p的下一个元素指向q的下一个,即跳过被删除元素q->next->prior = p; //q的下一个元素的前驱指向p,也跳过被删除的元素}free(q); //清空删除元素k = k - 1;}printf("删除成功\n");}六、测试结果1.最初运行程序时,有如下结果:2.在输入1后,创建长度为10的斐波那契数列,结果如下:3.在输入2后,显示数列,结果如下:4.在输入3后,进行查询操作后,结果如下:5.在输入4后,进行无序插入操作后,结果如下:6.在输入5后,进行有序插入操作后,结果如下:7.在输入6后,进行删除操作后,结果如下:8.输入其他数字的结果:七、总结反思刚做这个题目的时候发现自己结构体和链表学的太浅了,以前学得只是也不能很好的运用。

相关主题