定义双向链表的节点:
struct node
{
int data;
node * next; //指向后续节点
node * pre; //指向前面的节点
};
建立双向链表
新节点链入链尾
- 原链尾节点的后继指针指向新节点
- 新节点的前驱指针指向原链尾节点
- 新链尾节点的后继指针置为空指针
- 原链头节点的前驱指针指向新节点
- 新节点的后继指针指向原链头节点
- 新链头节点的前驱指针置为空指针
例子1:编写一个函数,按数据输入的顺序建立双向链表
node *createBidirList (int n)
{
node *temp, *tail = NULL, *head = NULL ;
int num;
cin >> num;
head = new node ; // 为新节点动态分配内存
if (head == NULL)
{
cout << "No memory available!";
return NULL;
}
else
{
head->data = num;
head->next = NULL;
head->pre = NULL;
tail = head;
}
for ( int i = 0; i < n - 1; i ++)
{
cin >> num;
temp = new node ; // 为新节点动态分配内存
if (temp == NULL)
{
cout << "No memory available!";
return head;
}
else
{
temp->data = num;
temp->next = NULL;
temp->pre = tail;
tail->next = temp;
tail = temp;
}
}
return head ;
}
双向链表的遍历
- 有链首节点,则可以沿着后继指针从头至尾遍历
- 有链尾节点,则可以沿着前驱指针从尾向头遍历
例子2:编写一个函数,输出双向链表中各节点的data成员的值
void outputBidirList(node * head)
{
cout << "List: ";
node *curNode = head;
while ( curNode )
{
if (curNode ->pre)
cout << " <- ";
cout << curNode->data;
if (curNode ->next)
cout << " -> ";
curNode = curNode ->next;
}
cout << endl;
return;
}
双向链表的操作
在双向链表中插入和删除一个节点
- 优点:获取插入节点或被删除节点的前驱和后继节点比较方便
- 注意点:需要维护的指针较多
例子3:编写函数,将整数n插入到一个已排序的双向链表中(从小到大)
node * insertData(int n, node * head)
{
node *curNode = head; // 指向插入点的后节点
node *preNode = NULL; // 指向插入点的前节点
node *newNode = NULL; // 指向新建节点
//寻找插入位置
while((curNode != NULL)&&(curNode->data < n))
{
preNode = curNode;
curNode = curNode->next;
}
newNode = new node ; // 为新节点动态分配内存
if (newNode == NULL)
{// 内存分配不成功
cout << "Not memory available!";
return head;
}
newNode->data = n;
if(preNode==NULL)
{ //链头
newNode->next = curNode;
newNode->pre = NULL;
if (curNode != NULL)
curNode->pre = newNode;
return newNode;
}
if (curNode == NULL)
{ // 链尾
newNode->pre = preNode;
preNode->next = newNode;
newNode->next = NULL;
return head;
}
else
{//链中
preNode->next = newNode;
newNode->next = curNode;
newNode->pre = preNode;
curNode->pre = newNode;
return head;
}
}
例子4:编写函数,在双向链表中查找并删除指定
node * deleteData(int n, node * head)
{
node *curNode = head; // 指向当前节点
while ( curNode && curNode->data != n)
curNode = curNode->next;
if (curNode == NULL)
{
cout<<"Can't find "<< n << endl;
return head;
}
if (curNode->pre == NULL)
{
head = head->next;
head->pre = NULL;
}
else
{
curNode->pre->next = curNode->next;
if (curNode->next != NULL)
curNode->next->pre=curNode->pre;
}
delete curNode;
return head; // 返回链首指针
}