双向链表的创建和相关操作
来源:互联网 发布:linux安装spark 编辑:程序博客网 时间:2024/05/23 19:14
双向链表其实是单链表的改进。 当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表结点的结构所限制的。因为单链表每个结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构呢?这就是双向链表。
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。
在c语言中双向链表结点类型可以定义为:
typedef struct Node{int item;struct Node *pre;struct Node *next;}DListNode,*DList;
下面的代码就是对双向链表的创建和相关操作:
/*************************************************************************** *name:jae chia * *date:2014.8.29 * *version: 1.0 * **************************************************************************/#include<iostream>#include<cassert>using namespace std;//双向链表的建立与操作typedef struct Node{int item;struct Node *pre;struct Node *next;}DListNode,*DList;DList InsertNodeToTail(DList head,int data)//将节点插入到双向链表的尾部{if(head==NULL){head=(DList)malloc(sizeof(DListNode));assert(head!=NULL);head->item=data;head->next=NULL;head->pre=NULL;}else{DListNode *newnode=(DList)malloc(sizeof(DListNode));//创建新的链表节点assert(newnode!=NULL);newnode->item=data;newnode->next=NULL;newnode->pre=NULL;DListNode *p=head;while(p->next!=NULL){p=p->next;}p->next=newnode;newnode->pre=p;}return head;}DList InsertDListByOrder(DList head,int data)//这里的插入操作是按序插入(保证双向链表中的节点以递增有序){DListNode *newnode=(DList)malloc(sizeof(DListNode));assert(newnode);newnode->item=data;//newnode->next=NULL;//newnode->pre=NULL;DListNode *p=head;DListNode *prenode;for(;p!=NULL;p=p->next){ prenode=p;if(newnode->item <=p->item)break; }if(p==NULL)//如果遍历整个链表,结点的值都比要插入的小,那么只能在尾端插入{prenode->next=newnode;newnode->pre=prenode;newnode->next=NULL;}else if(p==head)//如果链表中的数都比要插入的数大则在头部插入;{newnode->pre=NULL;newnode->next=head;head=newnode;}else //在中间插入{p->pre->next=newnode;newnode->pre=p->pre;newnode->next=p;p->pre=newnode;}return head;}bool FindNode(DList head,int data)//查找链表中含有某元素的节点是否存在{if(head==NULL){cout<<"the Dlist is NULL"<<endl;return false;}DListNode *p=head;while(p!=NULL){if(p->item==data)return true;p=p->next;}return false;}DList DeleteNode(DList head,int data)//删除节点{DListNode *p=head;while(p!=NULL){if(p->item==data)break;p=p->next;}if(p==NULL){cout<<"the node with data is not existed in the List"<<endl;exit(0);}if(p==head)//要删除的结点恰好是双向链表的头结点{DListNode *tmp=head;head=head->next;head->pre=NULL;//---------------------------------------------------free(tmp);}else if(p->next==NULL)//如果要删除的节点是链表的最后一个节点{p->pre->next=NULL;free(p);}else //删除中间节点{p->pre->next=p->next;p->next->pre=p->pre;}return head; }void PrintDList(DList head)//打印{cout<<"现在,链表如下:"<<endl;if(head==NULL){cout<<"the Dlist is NULL"<<endl;return ;}DListNode *p=head;while(p!=NULL){cout<<p->item<<" ";p=p->next;}cout<<endl<<endl;}void DestroyDList(DList head)//销毁双向链表{DListNode *p=head;while(p!=NULL){DListNode *tmp=p;p=p->next;free(tmp);}}void Test(){DListNode *head=NULL;for(int i=0;i<10;i++) /*利用尾部插入来构造双向链表*/head=InsertNodeToTail(head,i);PrintDList(head); int a;cout<<"输入要查找的结点的值"<<endl;cin>>a;if(FindNode(head,a))cout<<"结点存在!"<<endl<<endl;elsecout<<"结点不存在!"<<endl<<endl;cout<<"删除结点4..."<<endl; /*删除指定节点*/head=DeleteNode(head,4);PrintDList(head);cout<<"插入结点4..."<<endl; /*按序插入*/head=InsertDListByOrder(head,4); PrintDList(head); cout<<"删除头结点..."<<endl; /*删除指定节点*/head=DeleteNode(head,0);PrintDList(head); cout<<"删除尾结点..."<<endl;head=DeleteNode(head,9);PrintDList(head); cout<<"插入头结点..."<<endl; /*按序插入*/head=InsertDListByOrder(head,0); PrintDList(head);cout<<"插入尾结点..."<<endl; /*按序插入*/head=InsertDListByOrder(head,10); PrintDList(head); DestroyDList(head);}int main(void){Test();}
运行:
0 0
- 双向链表的创建和相关操作
- 双向链表的创建和相关操作
- 双向链表的相关操作
- 双向链表的创建和删除
- 双向链表的创建和读取
- 双向链表的相关操作C++实现
- 双向链表的相关操作--C语言实现
- 双向链表的相关操作C++实现
- 关于双向链表的相关一系列操作(作为备忘)
- 双向链表的相关操作C++实现
- 双向循环链表相关操作
- 双向循环链表的创建,插入,删除操作
- 双向循环链表的创建修改插入删除操作
- 双向链表的创建
- 【数据结构】双向链表的创建和读取
- 双向链表的操作
- 双向链表的操作
- 双向链表的操作
- 《JavaScript高级程序设计 第三版》学习笔记 (七) 内存泄漏详解
- 暑期英语总结
- hdu 1339
- Codeforces 463C Gargari and Bishops(贪心)
- android SQLite数据库
- 双向链表的创建和相关操作
- 喷水装置(一)
- 八月英语总结
- tab-size, word-wrap属性的应用
- 正则表达式学习正式记录
- Valid Parentheses
- hdu 1408
- -
- Codeforces Round #264 (Div. 2)C(找规律)