数据结构实验 建立双向循环链表以及插入删除操作
c语言双向链表的简单操作-创建、插入、删除

c语⾔双向链表的简单操作-创建、插⼊、删除数据结构-双向链表的创建、插⼊和删除双向链表是数据结构中重要的结构,也是线性结构中常⽤的数据结构,双向指针,⽅便⽤户从⾸结点开始沿指针链向后依次遍历每⼀个结点,结点的前驱和后继查找⽅便。
#include <stdio.h>#include <stdlib.h>//双向链表结点的定义typedef struct dbnode{int data;struct dbnode *prio, *next;}DbNode, linkdblist;//创建双向链表DbNode *creatlist(void){linkdblist *p, *q, *head;q = p = (linkdblist *)malloc(sizeof(linkdblist));p->next = NULL;head = q;p = (linkdblist *)malloc(sizeof(linkdblist));scanf("%d", &p->data);while (p->data != -1){q->next = p;p->prio = q;q = p;p = (linkdblist *)malloc(sizeof(linkdblist));scanf("%d", &p->data);}q->next = NULL;return head;}//输出双向链表void print(linkdblist *head){linkdblist *p;p = head->next;if (p == NULL)printf("空链表!\n");while (p != NULL){printf("%d ", p->data);p = p->next;}}//向双向链表中的第i个位置插⼊⼀个结点x void insertdblist(linkdblist *head, int x, int i) {linkdblist *p, *q = head;if (i == 1)q = head;else{q = q->next;int c = 1;while ((c<i - 1) && (q != NULL)){q = q->next;c++;}}if (q != NULL && q->next != NULL){p = (linkdblist *)malloc(sizeof(linkdblist)); p->data = x;p->prio = q;p->next = q->next;q->next = p;q->next->prio = p;}elseprintf("找不到插⼊的位置!");}//删除双向链表中指定位置上的⼀个结点void deletelinkdblist(linkdblist *head, int i) {linkdblist *p, *q = head;if (i == 1)q = head;else{q = q->next;int c = 1;while (c < i - 1 && q != NULL){q = q->next;c++;}}if (q != NULL && q->next != NULL){p = q->next;p->prio = q;p->prio->next = p->next;p->next->prio = p->prio;free(p);}else if (q->next == NULL){p = q;p->prio->next = NULL;free(p);}elseprintf("没有找到待删除的结点");}//双向链表的主函数void main(){linkdblist *head;head = creatlist();print(head);printf("\n\n====向双向链表的某位置插⼊⼀个值====\n"); int num, i;printf("输⼊插⼊的位置:");scanf("%d", &i);printf("\n输⼊插⼊的值:");scanf("%d", &num);insertdblist(head, num, i);print(head);printf("\n");printf("\n\n====删除双向链表的某位置上的⼀个值====\n"); int j;printf("输⼊删除的位置:");scanf("%d", &j);deletelinkdblist(head, j);print(head);system("pause");printf("\n");}。
建立双向链表 实现对双向链表的插入 删除操作1

#include <iostream>using namespace std;struct Node{int data; //节点中的数据结构体Node的成员变量Node* next; //指向下一节点的指针,习惯用next命名结构体Node的成员变量Node( const int& d=int() ) //结构体也可以有构造函数,d=T()来指定默认值:data(d),next(NULL) //用构造函数来初始化成员变量data和指针{} //所有数据类型,默认初始化都为0,这里data 默认初始化为0};class Chain //封装链表{private: //数据成员通常都是private的Node* head; //首先,我们要一个Node型的指针来保存链表的第一个节点;int length; //再用一个整型变量来记录当前链表内的节点数public:Chain() //在构造函数里建立一个空链表,即head指向NULL:head(NULL),length(0){} //节点数为0;//当我们在类中定义函数时(不是声明),相当于在前面加上一个inline修饰void delall() //这个函数用来删除链表中的所有节点{Node* pdel; //定义一个Node型指针用来保存要删除的节点while( head != NULL ) //当head的指向不为NULL时,就是链表中还存在节点{pdel = head; //这里备份head的当前指向节点head = head->next; //把head的指向改变为下一节点delete pdel; //把head的原指向给删除掉} //如此一直下去,尾节点的next肯定是指向NULL的,那删除最后一个的时候//head就被赋值为NULL,不满足循环条件,退出循环length = 0; //把节点数归零}~Chain(){ delall(); } //在析构函数中调用delall函数,来完成对象销毁时清理工作//这样一个链表必须具备的功能就实现了。
纯C语言实现循环双向链表创建,插入和删除

纯C语⾔实现循环双向链表创建,插⼊和删除#include <stdio.h>#include <stdlib.h>typedef int ElemType;typedef struct DLNode{ElemType data;struct DLNode *next;struct DLNode *prior;}DLNode;DLNode *InitList(DLNode *DL);//初始化int ListEmpty(DLNode *DL);//判空int ListLength(DLNode *DL);//返回链表长度int ListInsert(DLNode *DL, int i, ElemType e);//插⼊元素int ListDelete(DLNode *DL, int i);//删除第i个元素void TraverseList(DLNode *DL);//遍历线性表//初始化DLNode* InitList(DLNode *DL){int x;DLNode *p = NULL;DLNode *r = NULL;DL = (DLNode *)malloc(sizeof(DLNode));DL->next = DL;DL->prior = DL;r = DL;printf("输⼊直到-1为⽌\n");while(1){scanf("%d", &x);if(x == -1){printf("初始化成功\n");break;}p = (DLNode *)malloc(sizeof(DLNode));if(p){p->data = x;p->prior = r;p->next = DL;r->next = p;DL->prior = p;r = p;}else{printf("空间不⾜初始化失败\n");return NULL;}}return DL;}//判空int ListEmpty(DLNode *DL){return (DL->next == DL);}//插⼊元素int ListInsert(DLNode *DL, int i, ElemType e){if(i>ListLength(DL)+1 || i<=0){printf("插⼊位置有误,插⼊失败\n");return0;}DLNode *p = DL;int j = 0;while(j<i){p = p->next;j++;}DLNode *nDLNode = (DLNode *)malloc(sizeof(DLNode));nDLNode->data = e;nDLNode->prior = p->prior;p->prior->next = nDLNode;p->prior = nDLNode;nDLNode->next = p;printf("插⼊成功\n");return1;}//删除第i个元素int ListDelete(DLNode *DL, int i){if(i>ListLength(DL) || i<=0){printf("删除位置有误,插⼊失败\n");return0;}DLNode *p = DL;int j = 0;while(j<i){p = p->next;j++;}p->prior->next = p->next;p->next->prior = p->prior;free(p);printf("删除成功\n");return1;}//返回链表长度int ListLength(DLNode *DL){int len = 0;if(ListEmpty(DL)) return0;DLNode *p = DL->next;while(p->data!=DL->data){len++;p = p->next;}return len;}//遍历线性表void TraverseList(DLNode *DL){if(ListEmpty(DL)){printf("空链表");}DLNode *p = DL->next;//终⽌循环遍历while(p->data != DL->data){printf("%d ", p->data);p = p->next;}printf("\n");}int main(){ElemType e = NULL;DLNode *DL = NULL;//初始化测试DL = InitList(DL);////等价测试// DLNode *d = DL->next->next;// if(d->next->prior == d->prior->next){// printf("d->next->prior == d->prior->next\n");// }// if(d->next->prior == d){// printf("d->next->prior == d\n");// }// if(d == d->prior->next){// printf("d == d->prior->next\n");// }//遍历测试TraverseList(DL);//// printf("双向循环链表长度为%d\n",ListLength(DL));//插⼊元素测试printf("第3个位置插⼊999\n");ListInsert(DL, 3, 999);TraverseList(DL);//-----------------------------------------------------//⾮法操作?循环双向链表插⼊⼀个巨⼤的位置是否合法? //和⽼师讨论完,算不合法printf("第567位置插⼊999\n");ListInsert(DL, 567, 999);TraverseList(DL);//------------------------------------------------------//删除元素测试// printf("删除第1个位置\n");// ListDelete(DL, 1);// TraverseList(DL);//------------------------------------------------------//⾮法操作?同上//新问题,1,2,3,4,-1,删除第5个是头节点。
双向循环链表的创建及相关操作的实现课程设计说明书

双向循环链表的创建及相关操作的实现课程设计说明书山东建筑大学计算机科学与技术学院课程设计说明书题目: 双向链表的创建和操作的实现树的创建及相关操作的实现课程: 数据结构与算法院 (部): 计算机学院专业: 网络工程班级: 网络101学生姓名: 王天未学号: 2010111200指导教师: 伊静完成日期: 2013-7-6山东建筑大学计算机学院课程设计说明书目录课程设计任务书1 (II)课程设计任务书2............................................... III 双向循环链表的创建及相关操作的实现 (4)一、问题描述 (4)二、数据结构 (4)三、逻辑设计 (5)四、编码 (6)五、测试数据 (11)六、测试情况................................................ 11 树的创建及相关操作的实现 (15)一、问题描述 (15)二、数据结构 (15)三、逻辑设计 (16)四、编码 (19)五、测试数据 (26)六、测试情况................................................ 26 结论 .......................................................... 28 参考文献 ....................................................... 29 课程设计指导教师评语 . (30)I山东建筑大学计算机学院课程设计说明书山东建筑大学计算机科学与技术学院课程设计任务书1 设计题目双向循环链表的创建及相关操作的实现1、建立一个空表2、插入第i个结点。
已知技3、删除第i个结点。
术参数4、插入第1个结点。
和设计5、插入最后一个结点。
要求 6、逆置1、设计存储结构设计内2、设计算法容与步3、编写程序,进行调试骤4、总结并进行演示、讲解设计工作计做双向链表创建方法划与进度安做双向链表各种操作方法排1、考勤20% 设计考核要2、课程设计说明书50%求 3、成果展示30%指导教师(签字): 教研室主任(签字)II山东建筑大学计算机学院课程设计说明书山东建筑大学计算机科学与技术学院课程设计任务书2 设计题目树的创建及相关操作的实现1、利用先序遍历和层次遍历的结果建立二叉树2、实现二叉树的层次遍历已知技术参3、统计二叉树叶子结点的个数(递归)。
双循环链表算法描述

双循环链表算法描述双循环链表是一种特殊的链表结构,它有两个指针域,分别指向前一个节点和后一个节点,而最后一个节点指向头结点,头结点又指向第一个节点,形成了一个环形结构。
双循环链表可以用于实现队列和栈等数据结构,也可以用于解决某些问题。
双循环链表的基本操作包括插入、删除、查找和遍历等。
下面我们来详细介绍这些操作的算法描述。
1. 插入操作双循环链表的插入操作可以分为两种情况:在链表头部插入和在链表尾部插入。
具体算法描述如下:在链表头部插入:1. 创建一个新节点,并将其next指针指向头结点的next节点,将其prev指针指向头结点;2. 将头结点的next指针指向新节点,将新节点的next节点的prev 指针指向新节点。
在链表尾部插入:1. 创建一个新节点,并将其prev指针指向尾节点,将其next指针指向头结点;2. 将尾节点的next指针指向新节点,将头结点的prev指针指向新节点。
2. 删除操作双循环链表的删除操作也可以分为两种情况:删除头部节点和删除尾部节点。
具体算法描述如下:删除头部节点:1. 将头结点的next节点的prev指针指向头结点的prev节点;2. 将头结点的next指针指向头结点的next节点的next节点。
删除尾部节点:1. 将尾节点的prev节点的next指针指向尾节点的next节点;2. 将头结点的prev指针指向尾节点的prev节点。
3. 查找操作双循环链表的查找操作可以根据节点值或者节点位置进行。
具体算法描述如下:根据节点值查找:1. 从头结点的next节点开始遍历链表,直到找到节点值等于给定值的节点或者遍历到链表尾部;2. 如果找到了该节点,则返回该节点,否则返回NULL。
根据节点位置查找:1. 从头结点的next节点开始遍历链表,直到遍历到第i个节点或者遍历到链表尾部;2. 如果找到了该节点,则返回该节点,否则返回NULL。
4. 遍历操作双循环链表的遍历操作可以从头结点的next节点开始,依次访问每个节点。
数据结构中的双向链表插入删除与查找的优化策略

数据结构中的双向链表插入删除与查找的优化策略在数据结构中,双向链表是一种常见且实用的数据结构,它具有节点中既包含前驱节点指针(prev),也包含后继节点指针(next)的特点。
双向链表的插入、删除和查找操作是常见的基本操作,为了提高这些操作的效率,我们可以采用一些优化策略。
本文将讨论双向链表插入、删除和查找操作的优化方法。
一、双向链表的插入优化策略双向链表的插入操作是将一个新节点插入到链表中的某个位置,一般情况下,我们可以通过以下步骤进行插入操作:1. 找到插入位置的前驱节点;2. 创建新节点,并将新节点的prev指针指向前驱节点,next指针指向前驱节点的后继节点;3. 将前驱节点的next指针指向新节点,后继节点的prev指针指向新节点。
然而,在实际应用中,我们可以通过一些优化策略来减少插入操作的时间复杂度。
1. 将链表按照特定顺序进行排序:通过维护一个有序的双向链表,可以使插入操作更加高效。
当需要插入新节点时,只需要遍历链表找到合适的位置进行插入,而不需要像无序链表那样遍历整个链表。
2. 使用“哨兵”节点:在链表头和尾部分别设置一个“哨兵”节点,可以简化插入操作。
当插入新节点时,不需要再对头节点和尾节点进行特殊处理,直接按照一般插入操作即可。
二、双向链表的删除优化策略双向链表的删除操作是将链表中的某个节点删除,一般情况下,我们可以通过以下步骤进行删除操作:1. 找到待删除的节点;2. 将待删除节点的前驱节点的next指针指向待删除节点的后继节点;3. 将待删除节点的后继节点的prev指针指向待删除节点的前驱节点;4. 删除待删除节点。
同样地,我们可以通过一些优化策略来提高删除操作的效率。
1. 使用“快速删除”策略:在实际应用中,我们可能需要经常删除某个特定值的节点。
为了提高删除效率,可以使用一个哈希表来存储节点的值和对应的指针,可以将删除操作的时间复杂度从O(n)降低到O(1)。
2. 批量删除操作:如果需要删除多个节点,可以先将待删除的节点标记,并在删除操作时一次性删除所有标记的节点。
双向链表的创建,输出,插入数据和删除数据

双向链表的创建,输出,插⼊数据和删除数据#include <stdio.h>#include <stdlib.h>typedef struct aa{int data;struct aa *rlink;struct aa *llink;}DLink;DLink * createLink(DLink *head){//头节点DLink *p,*q;int n;head=p=(DLink *)malloc(sizeof(DLink));head->rlink=NULL;head->llink=NULL;scanf("%d",&n);while(n!=-1){//以输⼊-1作为输⼊数据的结束q=(DLink *)malloc(sizeof(DLink));q->llink=NULL;p->llink=q;q->rlink=p;p=p->llink;p->data=n;scanf("%d",&n);}return head;}void printLink(DLink *p){do{p=p->llink;printf("%d ",p->data);}while(p->llink!=NULL);}DLink * insertdate(DLink *head,int i,int n){int j;DLink *p=head;DLink *q;DLink *s;s=(DLink *)malloc(sizeof(DLink));s->data=n;if(p->llink==NULL){p->llink=s;s->rlink=p;return head;}q=p->llink;for(j=1;j<i&&q!=NULL;j++){p=p->llink;q=p->llink;}if(q==NULL){p->llink=s;s->rlink=q;}else{s->llink=q;q->rlink=s;p->llink=s;s->rlink=p;}return head;}DLink * deleteLink(DLink *head,int j){ int i=1;DLink *p=head,*q=head->llink;while(i<j&&q!=NULL){p=p->llink;q=q->llink;i++;}if(i==j){p->llink=q->llink;q->llink->rlink=p;}return head;}int main(){int i,j,n;//i是要插⼊的序号,n是要插⼊的数据,j是要删除的序号DLink *L;printf("请输⼊双向链表的数据,输⼊-1结束结束输⼊数据:");L=createLink(L);//创建链表printLink(L);//输出链表printf("请输⼊要插⼊的序号和数据(序号要⼤于0):");scanf("%d %d",&i,&n);L=insertdate(L,i,n);//插⼊数据printLink(L);printf("请输⼊请输⼊要删除数据的序号(序号要⼤于0且本序号有对应的数据):"); scanf("%d",&j);L=deleteLink(L,j);//删除链表printLink(L);}。
双向链表的建立插入删除算法的实现-数据结构课程设计

指导教师(签字): 批准日期: 2011 年 2 月 21 日
教研室主任(签字):
摘要
本课程设计采用 Visual C++作为软件开发环境,其具体的实现过程依次是:建立空指 针、构成双向链表、增加节点并给每个节点赋值,最后再通过所建链表进行插入、删除、 查找等程序,从而实现了链表问题求解,可以用一般的指针来实现,但是数据库中着重强 调了结构体,本程序用结构体指针更容易理解和实现初始化。
在双向链表中,若 d 为指向表中某一节点的指针(即 d 为 Du Link List 型变量),显 然有 d->next->prior=d->prior->next=d 这个表达式恰当的反应了这种结构的特性。
第 2页 共 27页
3 逻辑设计
此程序分为三大模块:数据输入模块、数据删除模块、数据查找模块。 数据输入模块完成数据的输入和存储,数据删除模块主要完成个人对没用的数据进行 删除,数据查找模块方便个人查找存储在里边的数据。 函数调用流程如图 3.
绩
指导教师
陈姣 0921024023
信 管 091
魏佳
计算机科学与技术系 2011 年 3 月 4 日
数据结构课程设计评阅书
题 目 双向链表的建立插入删除算法的实现
学生姓名 陈姣
学号 0921024023
指导教师评语及成绩
成绩:
教师签名:
答辩教师评语及成绩
年月日
成绩: 教研室意见
struct lnode *next,*prior;
// 表示 循环双链表
}lnode;
4.2 子函数设计
4.2.1 显示菜单设计
4.1 头文件设计......................................................................................................... 4 4.2 子函数设计......................................................................................................... 4
数据结构实验建立双向循环链表以及插入删除操作

数据结构实验建立双向循环链表以及插入删除操作实验一要求:①建立双向循环链表②实现链表的插入、删除运行程序点此处实验程序源代码:#include ""#include<>#include<>#define OVERFLOW -2#define ERROR 0#define OK 1typedef int status;//双向循环链表的存储结构typedef struct DuLNode{int data;int Length;struct DuLNode *prior;struct DuLNode *next;} DuLNode,*DuLinkList;//构建一个空的双向循环链表void InitList(DuLNode **p){*p=(DuLNode *)malloc(sizeof(DuLNode));if(*p){(*p)->next=(*p)->prior=*p;(*p)->Length=0;}elseexit(OVERFLOW);}//双向循环链表的创建void Create(DuLinkList &L,int n){//输入n个元素的值,建立带头结点的双线循环链表L DuLinkList p=L,q;int i;for(i=1;i<=n;i++){q=(DuLinkList)malloc(sizeof(DuLNode));printf("您该输入第%d个元素的值了:",i);scanf("%d",&q->data);p->next =q;q->prior=p;q->next=L;L->prior =q;p=q;L->Length ++;}}//查找元素的位置DuLinkList GetElemP(DuLinkList h,int i){int j;DuLinkList p=h;for(j=1;j<=i;j++)p=p->next ;return p;}//结点的插入status Listinsert(DuLNode *m,int i,int e){//在带头结点的双链循环线性表L中第i个位置之前插入元素e,i 的合法值为1≤i≤表长DuLinkList p,q;if(i<1||i>(m->Length)) // i值不合法return ERROR;p=GetElemP(m,i);if(!p)return ERROR;q=(DuLinkList)malloc(sizeof(DuLNode));if(!q)return OVERFLOW;q->data=e;q->prior=p->prior;p->prior->next=q;q->next=p;p->prior=q;m->Length++;printf("您在双向循环链表第%d个位置之前插入了一结点元素:%d\n",i,e);return OK;}//结点的删除status ListDelete(DuLinkList L,int i){//删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长DuLinkList p;if(i<1) /* i值不合法 */return ERROR;p=GetElemP(L,i);if(!p)return ERROR;p->prior->next=p->next;p->next->prior=p->prior;L->Length --;printf("删除了双线循环链表中第%d个结点,元素值为:%d\n",i,p->data); free(p);return OK;}//结点的输出void Display( DuLinkList L){ DuLinkList p;printf("双向循环链表中的结点的数据为:");for(p=L->next ;p->next !=L;){printf("%d",p->data);printf(" & ");p=p->next ;}printf("%d\n",p->data );}//主函数实现链表的创建,插入,删除等操作void main(){DuLinkList L;int n,i;InitList(&L) ;printf("你想创建几个循环节点就输入几就行啦,请输入:"); scanf("%d",&n);Create(L,n);Listinsert(L,3,3);//结点的插入printf("您想删除哪个结点呢");scanf("%d",&i);printf("您确定删除此结点吗1:YES 2:NO(回复数字确认)"); if(i=2){printf("您想删除哪个结点呢");scanf("%d",&i);ListDelete(L,i);}else{ListDelete(L,i);}//结点的删除Display(L);printf("双向循环链表中结点的个数为:%d\n",L->Length); }。
c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)

c++双向链表操作⽰例(创建双向链、双向链表中查找数据、插⼊数据等)双向链表也叫双链表,是链表的⼀种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。
所以,从双向链表中的任意⼀个结点开始,都可以很⽅便地访问它的前驱结点和后继结点。
⼀般我们都构造双向循环链表。
(1)定义双向链表的基本结构复制代码代码如下:typedef struct _DOUBLE_LINK_NODE{int data;struct _DOUBLE_LINK_NODE* prev;struct _DOUBLE_LINK_NODE* next;}DOUBLE_LINK_NODE;(2)创建双向链表节点复制代码代码如下:DOUBLE_LINK_NODE* create_double_link_node(int value){DOUBLE_LINK_NODE* pDLinkNode = NULL;pDLinkNode = (DOUBLE_LINK_NODE*)malloc(sizeof(DOUBLE_LINK_NODE));assert(NULL != pDLinkNode);memset(pDLinkNode, 0, sizeof(DOUBLE_LINK_NODE));pDLinkNode->data = value;return pDLinkNode;}(3)删除双向链表复制代码代码如下:void delete_all_double_link_node(DOUBLE_LINK_NODE** pDLinkNode){DOUBLE_LINK_NODE* pNode;if(NULL == *pDLinkNode)return ;pNode = *pDLinkNode;*pDLinkNode = pNode->next;free(pNode);delete_all_double_link_node(pDLinkNode);}(4)在双向链表中查找数据复制代码代码如下:DOUBLE_LINK_NODE* find_data_in_double_link(const DOUBLE_LINK_NODE* pDLinkNode, int data){DOUBLE_LINK_NODE* pNode = NULL;if(NULL == pDLinkNode)return NULL;pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){if(data == pNode->data)return pNode;pNode = pNode ->next;}return NULL;}(5)双向链表中插⼊数据复制代码代码如下:STATUS insert_data_into_double_link(DOUBLE_LINK_NODE** ppDLinkNode, int data) {DOUBLE_LINK_NODE* pNode;DOUBLE_LINK_NODE* pIndex;if(NULL == ppDLinkNode)return FALSE;if(NULL == *ppDLinkNode){pNode = create_double_link_node(data);assert(NULL != pNode);*ppDLinkNode = pNode;(*ppDLinkNode)->prev = (*ppDLinkNode)->next = NULL;return TRUE;}if(NULL != find_data_in_double_link(*ppDLinkNode, data))return FALSE;pNode = create_double_link_node(data);assert(NULL != pNode);pIndex = *ppDLinkNode;while(NULL != pIndex->next)pIndex = pIndex->next;pNode->prev = pIndex;pNode->next = pIndex->next;pIndex->next = pNode;return TRUE;}(6)双向链表中删除数据复制代码代码如下:STATUS delete_data_from_double_link(DOUBLE_LINK_NODE** ppDLinkNode, int data) {DOUBLE_LINK_NODE* pNode;if(NULL == ppDLinkNode || NULL == *ppDLinkNode)return FALSE;pNode = find_data_in_double_link(*ppDLinkNode, data);if(NULL == pNode)return FALSE;if(pNode == *ppDLinkNode){if(NULL == (*ppDLinkNode)->next){*ppDLinkNode = NULL;}else{*ppDLinkNode = pNode->next;(*ppDLinkNode)->prev = NULL;}}else{if(pNode->next)pNode->next->prev = pNode->prev;pNode->prev->next = pNode->next;}free(pNode);return TRUE;}(7)统计双向链表中数据的个数复制代码代码如下:int count_number_in_double_link(const DOUBLE_LINK_NODE* pDLinkNode){int count = 0;DOUBLE_LINK_NODE* pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){count ++;pNode = pNode->next;}return count;}(8)打印双向链表中数据复制代码代码如下:void print_double_link_node(const DOUBLE_LINK_NODE* pDLinkNode){DOUBLE_LINK_NODE* pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){printf("%d\n", pNode->data);pNode = pNode ->next;}}今天我们讨论的双向链表是⾮循环的,⼤家可以考虑⼀下如果改成循环双向链表,应该怎么写?如果是有序的循环双向链表,⼜该怎么写?。
链表(单链表 双向循环)实验报告讲解

数据结构实验报告T1223-3-21余帅实验一实验题目:仅仅做链表部分难度从上到下1.双向链表,带表头,线性表常规操作。
2.循环表,带表头,线性表常规操作。
3.单链表,带表头,线性表常规操作。
实验目的:了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。
实验要求:常规操作至少有:1.数据输入或建立2.遍历3.插入4.删除必须能多次反复运行实验主要步骤:1、分析、理解给出的示例程序。
2、调试程序,并设计输入数据,测试程序的如下功能:1.数据输入或建立2.遍历3.插入4.删除单链表示意图:headhead head 创建删除双向循环链表示意图:创建程序代码://单链表#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node *next;};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;searchp = searchp->next;count++;}searchp->next = NULL;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>=count)return range_error;node *newnodep=new node,*searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next=followp->next; //注意此处的次序相关性followp->next=newnodep;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp;if(empty())return underflow;searchp = headp->next;cout<<"连表中的数据为:"<<endl;while(searchp!=NULL){cout<<searchp->data<<" ";searchp = searchp->next;}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonfacevoid clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}/* 功能:用双向循环链表存储数据1.创建链表2.增加结点3.删除结点4.遍历链表制作人:余帅内容:239行*/#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node * next; //指向后续节点node * pre; //指向前面的节点};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;headp->pre = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;headp->pre = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;newnodep->pre = searchp;searchp = searchp->next;count++;}searchp->next = headp;headp->pre = searchp;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>count+1)return range_error;node *newnodep=new node;node *searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next = searchp;searchp->pre = newnodep;followp->next = newnodep;newnodep->pre = followp;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句searchp->next->pre = followp;delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp1,*searchp2;if(empty())return underflow;searchp1 = headp;searchp2 = headp;cout<<"连表中的数据为:"<<endl;cout<<"从左至右读取:";while (searchp1->next!=headp ) {searchp1 = searchp1 ->next;cout << searchp1->data<<" ";}cout<<endl;cout<<"从右至左读取:";while (searchp2->pre!=headp ) {searchp2 = searchp2 ->pre;cout << searchp2->data<<" ";}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonface void clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}运行结果:1.创建链表:2.增加结点3.删除结点心得体会:本次实验使我们对链表的实质了解更加明确了,对链表的一些基本操作也更加熟练了。
便于插入和删除的数据结构,双链表,循环链表

便于插入和删除的数据结构:双链表、循环链表1.双链表双链表是一种常见的数据结构,它的每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点。
相比于单链表,双链表能够更方便地进行插入和删除操作。
1.1双链表的节点结构双链表的节点结构可以定义如下:```m ar kd ow ns t ru ct No de{T d at a;//存储的数据N o de*p re v;//指向前一个节点的指针N o de*n ex t;//指向后一个节点的指针};```1.2双链表的插入操作在双链表中插入一个节点,需要将该节点的前后指针分别指向前一个节点和后一个节点,并将前一个节点的后指针和后一个节点的前指针分别指向待插入节点。
具体步骤如下:1.创建一个新节点,并给新节点赋值。
2.将新节点的前指针指向前一个节点,后指针指向后一个节点。
3.将前一个节点的后指针指向新节点,后一个节点的前指针指向新节点。
1.3双链表的删除操作在双链表中删除一个节点,需要将该节点的前后节点的指针重新连接起来,并释放待删除节点的内存空间。
具体步骤如下:1.找到待删除节点。
2.将待删除节点的前一个节点的后指针指向待删除节点的后一个节点。
3.将待删除节点的后一个节点的前指针指向待删除节点的前一个节点。
4.释放待删除节点的内存空间。
2.循环链表循环链表是一种特殊的链表,它的最后一个节点的后指针指向头节点,形成一个循环。
循环链表同样可以便于插入和删除操作。
2.1循环链表的节点结构循环链表的节点结构与单链表的节点结构相似,只是在最后一个节点的后指针处做了特殊处理:```m ar kd ow ns t ru ct No de{T d at a;//存储的数据N o de*n ex t;//指向下一个节点的指针};```2.2循环链表的插入操作循环链表的插入操作与单链表类似,只需要将插入节点的后指针指向下一个节点,并将上一个节点的后指针指向插入节点。
双链表实验报告的构造、插入、删除和显示.doc

双链表实验报告的构造、插入、删除和显示.1.实验目的:1)掌握双链表的逻辑特征;2)熟练掌握带前导节点的双链表的指针操作,能够完成双链表的构造、插入、删除和显示等复杂应用。
2.实验原理在双向链表的节点中有两个指针字段,一个指向直接后继,另一个指向直接前一个,这可以用C语言描述如下: typedef结构DuLNode{ElemType数据;结构DuLNode *优先;结构DuLNode * next}DuLNode,* DuLinkList双链表的操作类似于单链表。
这个实验使用函数和指针的知识来处理双链表。
首先,建立了四个功能。
创建、打印、列表插入_ DUL、列表删除_ DUL分别实现双链表的建立、输出、插入和删除功能。
需要建立GetElemP_DuL函数来提供帮助。
然后这五个功能被组织在一个C程序中,并且主功能被用作主功能。
3.实验内容1。
首先,建立一个带前导节点的非空双向链表。
创建函数creat类似于创建线性链表,但是两个方向的指针都需要修改。
本实验以6名学生的数据为例。
2.建立函数获取第一个元素的位置指针。
3.插入链接列表。
建立函数列表插入_模块,输入要插入的学生数据和位置,调用函数GetElemP _模块,如果插入成功返回1,否则返回0。
4.删除链接列表。
建立函数列表删除模块,输入要删除的学生的位置,调用函数获取模块,如果删除成功返回1,否则返回0。
5.输出并显示链表结果。
建立功能打印,以正向和反向输出链表。
6.确定主要功能,并将上述五个功能整合到一个程序中。
当输入数据不为0时,可以多次删除和插入,并显示每次的结果。
四.实验方法的操作环境:Visual C 6.0将所有的程序思想编写成代码,通过Visual C进行编译,得到结果,即操作成功。
本实验的程序代码:# include ' stdio . h ' # include ' malloc . h ' # define NULL 0 # define LEN size of(struct student)# define OK 1 # define ERROR 0 struct student { int数据;struct学生*优先;struct student * next};int n;结构化学生*创建(空){结构化学生* L;struct student * p1,* p2l=(struct student *)malloc(LEN);1)掌握双链表的逻辑特征2)熟练掌握双链表与头节点的指针操作,能够完成双链表的构造、插入、删除和显示等复杂应用。
双链表的建立插入删除算法的实现

双链表的建立插入删除算法的实现摘要设计一个个人电话本,该电话本是基于双链表的具体功能实现,双链表的主要功能是查找、删除和插入。
其具体的实现过程:依次是建立空指针、构成双向链表、增加结点并给每个结点赋值,最后再通过所建链表进行插入,删除,查找等程序,从而实现了链表问题求解.可以用一般的指针来实现,但是数据库中着重强调了结构体,本题用结构体指针更容易理解和实现和初始化。
关键字:双链表;直接前驱;直接后继;节点;目录1 课程设计内容 (6)2 设计要求 (7)2.1 问题定义和任务分析 (7)2.2 逻辑设计 (7)2.3 详细设计 (8)2.4程序流程图 (11)2.5.程序编码 (12)2.6 程序的调试与测试 (15)总结 (18)参考文献 (19)1 课程设计内容用C/C++编写一个程序实现双向链表的建立、插入、删除算法。
要求建立的链表要有一定的应用价值,具体应用内容设计者自己确定。
建立双向链表必须运用结构体建立两个指针,先定义一个双链节点--但是,它的名字必须叫Node,当你派生双向链表时,这样写template <calss Type>class DblList : public List<newtype<Type >>,注意连续的两个">"之间要有空格。
或者根本不定义这样的结构,直接拿Node类型来做。
开发工具:visual C++6.02 设计要求本次设计是基于visual C++作为开发环境,采用双链表的插入删除查找等功能,来实现个人电话本的相应功能。
2.1 问题定义和任务分析通过题目要求本课题是用C/C++来实现双链表的插入删除查找的功能,具体应用于个人电话本,电话本中含有存储姓名和电话(电话号码使用整型,姓名使用字符型)。
双链表的节点中有两个指针域,其一指向直接后继,另一个指向直接前继。
和单链表的循环类似,双链表也可以有循环表。
在双向链表中,若d为指向表中某一结点的指针(即d为DuLinkList型变量),显然有d->next->prior=d->prior->next=d这个表示式恰当地反映了这种结构的特性。
数据结构双向循环链表

题目:试编写一个在循环双向链表中进行删除操作的算法,要求删除的结点是指定结点p 的前趋结点。
主函数:#include <stdio.h>#include "List_Link.h"long InsElement(PLINKNODE_S pstSqList){int nElement;int nPosition;printf("请输入合法INT值: ");scanf("%d", &nElement);printf("请输入合法INT值作为元素在顺序表中位置: ");scanf("%d", &nPosition);if (InsertList_L(pstSqList, nPosition, nElement))//向链表中插入数据以及指定数据在链表中的位置{printf("插入操作成功\n\n");}else{printf("输入非法INT值,插入操作失败\n\n");}return 0;}long DelElement(PLINKNODE_S pstSqList){int nPosition;int nElement;printf("请输入合法INT值在顺序表中位置: ");scanf("%d", &nPosition);if (DeleteList_L(pstSqList, nPosition, &nElement))//指定数据在链表中的位置,删除该节点{printf("删除操作成功\n\n");}else{printf("输入非法INT值,删除操作失败\n\n");}return 0;}int main(){PLINKNODE_S pstLinkList;char szCommond[10];pstLinkList = (PLINKNODE_S)malloc(sizeof(LINKNODE_S));pstLinkList->nElem = 0; //通常头结点不赋值pstLinkList->pNext = pstLinkList; //将头结点的后继结点指针指向空printf("操作命令: \n");printf("i ------- 插入, d ------- 删除\n");printf("e ------- 退出, s ------- 显示当前线性表\n");printf("\n删除操作将删除指定结点的前驱结点!\n\n");while (OK){scanf("%s", &szCommond);if (szCommond[0] == 'i'){InsElement(pstLinkList);}else if (szCommond[0] == 'd'){DelElement(pstLinkList);}else if (szCommond[0] == 'e'){break;}else if (szCommond[0] == 's'){DisplayList_L(pstLinkList);}}DestoryList_L(pstLinkList);return 0;}头文件:#ifdef _cplusplusextern "C"{#endif#include <stdio.h>#include <Windows.h>#define STATUS int#define ERROR 0#define OK 1typedef struct tagLinkNode{int nElem;struct tagLinkNode *prior;struct tagLinkNode *pNext;}LINKNODE_S, *PLINKNODE_S;STATUS InsertList_L(PLINKNODE_S pstHeadNode, int nPosition, int nElement) {PLINKNODE_S p, s;int i = 0;p = pstHeadNode;while (p && i < nPosition-1){ // 寻找第nPosition-1个结点p = p->pNext;++i;}if (!p || i > nPosition-1){return ERROR; // i小于1或者大于表长}s = (PLINKNODE_S)malloc(sizeof(LINKNODE_S)); // 生成新结点s->pNext = NULL; //将结构中指针初始化为空值s->nElem = nElement;s->pNext = p->pNext; // 插入L中s->prior = p;p->pNext = s;s->pNext->prior = s; //头结点的前驱指向尾结点return OK;}STATUS DeleteList_L(PLINKNODE_S pstHeadNode, int nPosition, int *nElem){PLINKNODE_S p;int nTemp = 0;p = pstHeadNode;while (p->pNext && nTemp < nPosition - 1) //寻找第i个节点,并令p指向其前趋节点{p = p->pNext;++nTemp;}if (!(p->pNext) || (nTemp > nPosition - 1)){return ERROR; //删除位置不合理}if(!nTemp)p = p->prior; //如果输入1,则p移动到尾结点p->prior->pNext = p->pNext;p->pNext->prior = p->prior;free(p);return OK;}STATUS DisplayList_L(PLINKNODE_S pstHeadNode){PLINKNODE_S pScanNode;pScanNode = pstHeadNode;printf("HEAD <-> ");while (pScanNode->pNext != pstHeadNode){pScanNode = pScanNode->pNext;printf("%d <-> ", pScanNode->nElem);}printf("NULL\n");return OK;}STATUS DestoryList_L(PLINKNODE_S pstHeadNode) {PLINKNODE_S pScanNode, pTempNode;pScanNode = pstHeadNode;if (NULL == pstHeadNode){return ERROR;}while (pScanNode->pNext != pstHeadNode){pTempNode = pScanNode;pScanNode = pScanNode->pNext;free(pTempNode);}return OK;}#ifdef _cplusplus}#endif。
双链表的建立,插入,删除,我自己写的

////////建立#include <iostream>#include <stdio.h>#include <string.h>#include <conio.h>using namespace std;//定义结构体typedef strunct student{int data; //定义数据域strunct student *next; //指向后继结点strunct student *pre; //指向前驱结点}dnode;//创建双链表函数dnode *creat() //返回值是指针{dnode *head,*P,*s;int x,cycle=1;head=(dnode*)malloc(sizeof(dnode)); //分配内存p=head;while(cycle){pritf("\n please input the data:");scanf("%d",&x);if(x!=0){s=(dnode*)malloc(sizeof(dnode));s->data=x;printf("\n %d",s->data);p->next=s;s->pre=p;p=s;}else cycle=0; //跳出while循环}head=head->next;head->pre=NULL;p->next=NULL;printf("\n yyy %d",head->data);return(head);}////////插入dnode *Insert(d node *head,int item,int num){node *p0,*p1,*p2; /*p0是要插入的节点,p2是要插入节点的前一个节点,p1是要插入节点的后一个节点*/p1=head;if ((p0=(node *)malloc(sizeof(node)))==NULL){printf("error");exit(0);}p0->data=item;for (int i=1;i<num;i++) /*遍历到插入的位置*/{p2=p1;p1=p1->next;}if(p1==head) /*如果是插入头节点*/{head=p0;p0->next=p1;p1->pre=p0;p0->pre=NULL;}else if(p1->next==NULL)/*如果是插入末节点*/{p1->next=p0;p0->pre=p1;p0->next=NULL;}else{p2->next = p0;po->pre = p2;p0->next = p1;p1->pre = p0;}return(head);}////////删除dnode *del(dnode *head, int num ){dnode *p1,*p2; //删除p1,P2是p1前面的结点p1=head;for(int i=0;i<num;i++){p2=p1;p1=p1->next;}if(p1==head){head=p1->next;p1->next->pre=NULL;free(p1);}else if(p1->next=NULL){p2->next=NULL;p2->next->pre=NULL;free(p1);}else{p2->next=p1->next;p1->next->pre=p2;free(p1);}return(head);}。
双向链表插入删除基本操作演示 精选文档

return ERROR;
s->data=e;
① s->prior=p->prior;
② p->prior->next=s;
③ s->next=p;
p
④ p->prior=s;
return OK;
a
b
}
①
s
e
在双向链表中插入结点
Status ListInsert_Dul(DuLinklist &L,int i,ElemType e)
{
if(!(p=GetElem_DuL(L,i)))
return ERROR;
if(!(s=(DuLinkList)malloc(sizeof(DuLNode))))
return ERROR;
s->data=e;
① s->prior=p->prior;
② p->prior->next=s;
③ s->next=p;
return ERROR;
s->data=e;
① s->prior=p->prior;
② p->prior->next=s;
③ s->next=p;
p
④ p->prior=s;
return OK;
a
b
}
① ②④ ③
s
e
在双向链表中删除结点
Status ListDelete_Dul(DuLinklist &L,int i,ElemType &e)
return ERROR;
s->data=e;
① s->prior=p->prior;
双链表(初始化,建立,插入,查找,删除)

双链表(初始化,建⽴,插⼊,查找,删除)双向链表和单向链表也是有很多相似的地⽅的,听名字可以猜到,每个节点都包含两个指针,⼀个指针指向上⼀个节点,⼀个指针指向下⼀个节点。
这⾥有两个特殊的地⽅,第⼀就是头节点的⼀个指针指向NULL空指针(没有前驱节点),第⼆就是尾节点的⼀个指针指向NULL指针(没有后继节点)。
#ifndef DOUBLY_LINKED_LIST_H#define DOUBLY_LINKED_LIST_Htypedef struct Node{int data;struct Node *pNext;struct Node *pPre;}NODE, *pNODE;//创建双向链表pNODE CreateDbLinkList(void);//打印链表void TraverseDbLinkList(pNODE pHead);//判断链表是否为空int IsEmptyDbLinkList(pNODE pHead);//计算链表长度int GetLengthDbLinkList(pNODE pHead);//向链表插⼊节点int InsertEleDbLinkList(pNODE pHead, int pos, int data);//从链表删除节点int DeleteEleDbLinkList(pNODE pHead, int pos);//删除整个链表,释放内存void FreeMemory(pNODE *ppHead);#endifDbLinkList.cpp 双向链表的源⽂件——包含了各种操作函数的定义。
(1)这部分是创建双向链表,和单向链表很相似,但是呢,有些地⽅还是得注意,就是每创建⼀个节点的时候都要注意初始化它的两个指针。
#include <stdio.h>#include <stdlib.h>#include "DbLinkList.h"//创建双向链表pNODE CreateDbLinkList(void){int i, length = 0, data = 0;pNODE pTail = NULL, p_new = NULL;pNODE pHead = (pNODE)malloc(sizeof(NODE));if (NULL == pHead){printf("内存分配失败!\n");exit(EXIT_FAILURE);}pHead->data = 0;pHead->pPre = NULL;pHead->pNext = NULL;pTail = pHead;printf("请输⼊想要创建链表的长度:");scanf("%d", &length);for (i=1; i<length+1; i++){p_new = (pNODE)malloc(sizeof(NODE));if (NULL == p_new){printf("内存分配失败!\n");exit(EXIT_FAILURE);}printf("请输⼊第%d个元素的值:", i);scanf("%d", &data);p_new->data = data;p_new->pNext = NULL;p_new->pPre = pTail;pTail->pNext = p_new;pTail = p_new;}return pHead;}(2)这部分是获得双向链表的信息,这⾥和单向链表基本⼀致,因为遍历的时候只⽤到了⼀个指针。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
q->prior=p;
q->next=L;
L->prior =q;
p=q;
L->Length ++;
}
}
//查找元素的位置
DuLinkList GetElemP(DuLinkList h,int i)
{
int j;
DuLinkList p=h;
for(j=1;j<=i;j++)
p=p->next ;
return p;
}
//结点的插入
status Listinsert(DuLNode *m,int i,int e)
{
//在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长
DuLinkList p,q;
if(i<1||i>(m->Length)) // i值不合法
typedef int status;
//双向循环链表的存储结构
typedef struct DuLNode
{
int data;
int Length;
struct DuLNode *prior;
struct DuLNode *next;
} DuLNode,*DuLinkList;
//构建一个空的双向循环链表
Create(L,n);
Listinsert(L,3,3);//结点的插入
printf("您想删除哪个结点呢?");
scanf("%d",&i);
printf("您确定删除此结点吗?1:YES 2:NO(回复数字确认)");
if(i=2)
{
printf("您想删除哪个结点呢?");
scanf("%d",&i);
return ERROR;
p=GetElemP(m,i);
if(!p)
return ERROR;
q=(DuLinkList)malloc(sizeof(DuLNode));
if(!q)
return OVERFLOW;
q->data=e;
q->prior=p->prior;
p->prior->next=q;
p=p->next ;
}
printf("%d\n",p->data );
}
//主函数实现链表的创建,插入,删除等操作
void main()
{
DuLinkList L;
int n,i;
InitList(&L) ;
printf("你想创建几个循环节点就输入几就行啦,请输入:");
scanf("%d",&n);
void InitList(DuLNode **p)
{
*p=(DuLNode *)malloc(sizeof(DuLNode));
if(*p)
{
(*p)->next=(*p)->prior=*p;
(*p)->Length=0;
}
else
exit(OVERFLOW);
}
//双向循环链表的创建
void Create(DuLinkList &L,int n)
实验一
要求:①建立双向循环链表
②实现链表的插入、删除
运行程序点此处Demo_1.exe
实验程序源代码:
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#define OVERFLOW -2
#define ERROR 0
#define OK 1
q->next=p;
p->prior=q;
m->Length++;
printf("您在双向循环链表第%d个位置之前插入了一结点元素:%d\n",i,e);
return OK;
}
//结点的删除
status ListDelete(DuLinkList L,int i)
{
//删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长
{
//输入n个元素的值,建立带头结点的双线循环链表L
DuLinkList p=L,q;
int i;
for(i=1;i<=n;i++)
{
q=(DuLink);
printf("您该输入第%d个元素的值了:",i);
scanf("%d",&q->data);
ListDelete(L,i);
}
else
{ListDelete(L,i);}//结点的删除
Display(L);
printf("双向循环链表中结点的个数为:%d\n",L->Length);
}
DuLinkList p;
if(i<1) /* i值不合法*/
return ERROR;
p=GetElemP(L,i);
if(!p)
return ERROR;
p->prior->next=p->next;
p->next->prior=p->prior;
L->Length --;
printf("删除了双线循环链表中第%d个结点,元素值为:%d\n",i,p->data);
free(p);
return OK;
}
//结点的输出
void Display( DuLinkList L)
{ DuLinkList p;
printf("双向循环链表中的结点的数据为:");
for(p=L->next ;p->next !=L;)
{
printf("%d",p->data);
printf(" & ");