-
意義:
解決單鏈表的由於方向性引起的效率問題
單鏈表有個缺陷,就是當數據量比較大的時候,當需要對已知節點做刪除,排序的等操作時,有一個問題,就是當需要從頭節點開始遍歷,往往效率較低,
head==>1 ==> 2 ==>3 ==>4==5
當我需要刪除3這個結點時,就得知道2這個結點的指針,但是隻能從頭指針開始遍歷,才能知道
雙向鏈表的指針域,除了包含一個後繼指針外還包括一個前驅指針,這樣子,當擁有一個已知結點時,就不要從頭遍歷就可以知道這個指針的前驅指針,直接使用即可
head<==> 1<==>2<==>3
當已知3這個結點時,可以通過前驅指針,得到2這個結點的指針,然後可以做相應的處理
2.實現
2.1 數據結構
typedef struct node
{
int data; //數據域
struct node *next; //指針域
struct node *prep;
}NODE_t;
next 爲後繼指針,prep爲前驅指針
2.2 創建
NODE_t *CreatNodeList()
{
NODE_t *head = NULL;
head = (NODE_t *)malloc(sizeof(NODE_t));
if(!head)
exit(-1);
head->next = NULL;
head->prep = NULL;
return head;
}
2.2 插入
int InsertNode(NODE_t *head,int data)
{
NODE_t *cur = NULL;
if(!head)
exit(-1);
cur = (NODE_t *)malloc(sizeof(NODE_t));
if(!cur)
exit(-1);
cur->data = data;
if(!head->next)
{
// 當只有頭節點時
cur->next = head->next;
cur->prep = head;
head->next = cur;
}
else
{
// 當鏈表有節點元素時
cur->next = head->next;
head->next->prep = cur;
cur->prep = head;
head->next = cur;
}
return 0;
}
2.3 查找
NODE_t *findNode(NODE_t *head,int data)
{
head = head->next;
while(head)
{
if(head->data == data)
{
break;
}
head = head->next;
}
if(head == NULL)
{
printf("sorry,%d is not in the list\n",data);
}
return head;
}
2.4 刪除
int DeleteNodeOfList(NODE_t *head,NODE_t *pfind)
{
if(pfind->next != NULL)
{
pfind->prep->next = pfind->next;
pfind->next->prep = pfind->prep;
}
else
{
// 處理尾節點
pfind->prep->next = NULL;
}
free(pfind);
pfind = NULL;
return 0;
}
2.5 修改
int UpdateNode(NODE_t *head,int olddata,int newdata)
{
NODE_t *p = findNode(head,olddata);
if(p)
{
p->data = newdata;
}
return 0;
}
2.6 排序
int sortList(NODE_t *head)
{
int i = 0,j = 0;
int listlen = 0;
int tmpData = 0;
NODE_t *p = NULL;
// 使用冒泡排序,不動指針域,比較數據域,使用臨時變量,將有大小之別的節點的數據域交換
// 得到鏈表長度,方便冒泡
listlen = ListNodeLen(head);
// 指到首節點
p = head->next;
for(i = 0;i < listlen-1;i++)
{
// 每一輪從頭開始
p = head->next;
for(j = 0;j<listlen - i-1;j++)
{
// 將小值排在前面
if(p->data > p->next->data)
{
tmpData = p->data;
p->data = p->next->data;
p->next->data = tmpData;
}
p = p->next;
}
}
return 0;
}