http://blog.csdn.net/jw903/article/details/38947753
双向链表其实是单链表的改进。 当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表结点的结构所限制的。因为单链表每个结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构呢?这就是双向链表。
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。
在c语言中双向链表结点类型可以定义为:
[cpp] view plain copy
- typedef struct Node
- {
- int item;
- struct Node *pre;
- struct Node *next;
- }DListNode,*DList;
下面的代码就是对双向链表的创建和相关操作:
[cpp] view plain copy
- /***************************************************************************
- *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;
- else
- cout<<"结点不存在!"<<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();
- }
运行: