双链表
1、双向链表(Double Linked List)
双(向)链表中有两条方向不同的链
即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前趋的指针域prior。
注意:
①双链表由头指针head惟一确定的。
②带头结点的双链表的某些运算变得方便。
③将头结点和尾结点链接起来,为双(向)循环链表。
2、双向链表的结点结构和形式描述
①结点结构(见上图a)
②形式描述
typedef struct dlistnode{
DataType data;
struct dlistnode *prior,*next;
}DListNode;
typedef DListNode *DLinkList;
DLinkList head;
3、双向链表的前插和删除本结点操作
由于双链表的对称性,在双链表能能方便地完成各种插入、删除操作。
①双链表的前插操作
void DDeleteNode(DListNode *p)
{//在带头结点的双链表中,删除结点*p,设*p为非终端结点
p->prior->next=p->next;//①
p->next->prior=p->prior;//②
free(p);//③
}
注意:
与单链表上的插入和删除操作不同的是,在双链表中插入和删除必须同时修改两个方向上的指针。
上述两个算法的时间复杂度均为O(1)。
代码实现:
#include <iostream>
using namespace std;
int N = 10;
struct Node
{
char name[20];
Node *pre, *next;
};
Node *create(int n)
{
Node *h, *p, *s; //h:头结点,p:下一结点,s:当前结点
int i;
h = new Node;
h->name[0] = 0;
h->pre = NULL;
h->next = NULL;
p = h;
for (i=0; i!=n; ++i)
{
s = new Node;
p->next = s;
cout<<"Enter the "<<i+1<<" name:"<<endl;
cin>>s->name;
s->pre = p;
s->next = NULL;
p = s;
}
s->next = h;
h->pre = s;
return h;
}
Node *Search(Node *h, const char *name)
{
Node *p = h->next;
for (int i=0;i!=N;++i)
{
if (strcmp(p->name,name)==0)
{
return p;
}
p = p->next;
}
return p;
}
void Insert(Node *p)
{
Node *s = new Node;
cout<<"Enter the name to insert:"<<endl;
cin>>s->name;
Node *r = p->next; //结点示意 p->s->r(s为插入的结点)
p->next = s;
s->pre = p;
r->pre = s;
s->next = r;
++N;
}
void Delete(Node *p)
{
Node *l = p->pre; //结点示意 l->p->r (p为要删除的结点)
Node *r = p->next;
l->next = r;
r->pre = l;
delete p;
--N;
}
void Display(Node *h)
{
Node *p;
p = h->next;
for (int i=0;i!=N;++i)
{
cout<<"The "<<i+1<<" name:"<<p->name<<endl;
p = p->next;
}
}
int main()
{
Node *head, *pSearch;
int number = N;
char strName[20];
head = create(number);
cout<<"The structure you create:"<<endl;
Display(head);
//查找并插入...
cout<<"Enter the name to find:"<<endl;
cin>>strName;
pSearch = Search(head,strName);
cout<<"The name you find: "<<pSearch->name<<endl;
Insert(pSearch);
cout<<"After insert:"<<endl;
Display(head);
//查找并删除...
cout<<"Enter the Node to delete:"<<endl;
cin>>strName;
pSearch = Search(head,strName);
Delete(pSearch);
cout<<"After delete:"<<endl;
Display(head);
return 0;
}