双向链表的创建和相关操作
2014-08-30 21:34
316 查看
双向链表其实是单链表的改进。 当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表结点的结构所限制的。因为单链表每个结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构呢?这就是双向链表。
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。
在c语言中双向链表结点类型可以定义为:
下面的代码就是对双向链表的创建和相关操作:
运行:
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。
在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;
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();
}
运行:
相关文章推荐
- 链表的创建和相关操作(Linux下Vim编制)
- 双向链表的有关操作(创建,遍历,插入,删除)
- 双向链表的建立与相关操作
- (C++版)链表(一)——实现单向链表创建、插入、删除等相关操作
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- !-- 带头结点带环的双向链表的相关操作实现 --!
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- (C++版)链表(四)——实现双向循环链表创建、插入、删除等简单操作
- 双向链表的相关操作C++实现
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- 单向链表的相关操作(创建,遍历,插入,删除,逆置)
- 单向链表的相关操作总结:创建、删除、查找、排序、统计链表大小、链表的反转和遍历等
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- 带头带环双向链表的实现及其相关操作。。
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
- 双向链表的相关操作C++实现
- (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
- (C++版)链表(三)——实现双向链表的创建、插入、删除等简单操作