【資料結構】雙向帶頭結點迴圈連結串列
阿新 • • 發佈:2018-12-28
在之前我們寫了不帶頭結點的單鏈表,但它在資料操作時也有繁瑣之處,而雙向帶頭結點迴圈連結串列則優化了單鏈表的操作,使連結串列更加方便。雙向帶頭結點迴圈連結串列在單鏈表的基礎上增加了以下幾點:
(1)在資料結構上附加一個域,使它存放指向前一個結點的指標;
(2)增加了一個頭結點,前驅指向連結串列的最後一個結點;
(3)連結串列的最後一個結點指向頭結點,使它構成一個迴圈連結串列。
資料型別的定義
typedef int DataType; typedef struct Node { DataType data; struct Node *prev; struct Node *next; }Node;
連結串列的初始化、銷燬和列印
- 初始化
void ListInit(Node *head)
{
assert(head);
head->data = 0;
head->next = head;
head->prev = head;
}
- 銷燬
連結串列的銷燬要一個個結點去銷燬,然後剩下一個頭結點,釋放頭結點。
void ListDestory(Node *head) { Node *ret = NULL; Node *cur = NULL; assert(head); cur = head->next; while(cur != head) { ret = cur->next; cur->next = NULL; cur->prev = NULL; ret->prev = head; cur = ret; } free(head); head->next = NULL; head->prev = NULL; }
- 列印連結串列
void ListPrint(Node *head)
{
Node *cur = NULL;
assert(head);
cur = head->next;
printf("head--->");
while(cur != head)
{
printf("%d--->",cur->data);
cur = cur->next;
}
printf("NULL");
printf("\n");
}
連結串列的查詢
Node *Find(Node *head, DataType data) { Node *cur = NULL; assert(head); cur = head->next; while(cur != head) { if(cur->data == data) { return cur; } cur = cur->next; } return NULL; }
增加資料
在增加資料前,需要一個函式來建立一個新結點,函式返回新結點的地址,通過改變連結串列中結點的next指向來將新結點加入到連結串列中。程式碼如下:
Node *CreateNode(DataType data)
{
Node *newNode = (Node *)malloc(sizeof(Node));
assert(newNode);
newNode->data = data;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
插入結點
程式碼如下:
//頭插
void PushFront(Node *head, DataType data)
{
Node *newNode = CreateNode(data);
newNode->prev = head;
newNode->next = head->next;
head->next->prev = newNode;
head->next = newNode;
}
//尾插
void PushBack(Node *head, DataType data)
{
Node *newNode = CreateNode(data);
newNode->prev = head->prev;
newNode->next = head;
head->prev->next = newNode;
head->prev = newNode;
}
//任意位置前插入
void Insert(Node *head, Node *pos, DataType data)
{
Node *newNode = CreateNode(data);
assert(head);
assert(pos);
newNode->next = pos;
newNode->prev = pos->prev;
pos->prev->next = newNode;
pos->prev = newNode;
}
執行結果
刪除資料
程式碼如下:
//頭刪
void PopFront(Node *head)
{
Node *del = NULL;
if(head->next == NULL)
{
printf("連結串列為空,刪除失敗\n");
return ;
}
del = head->next;
head->next = del->next;
del->next->prev = head;
free(del);
del->next = NULL;
del->prev = NULL;
}
//尾刪
void PopBack(Node *head)
{
Node *del = NULL;
if(head->next == NULL)
{
printf("連結串列為空,刪除失敗\n");
return ;
}
del = head->prev;
head->prev = del->prev;
del->prev->next = head;
free(del);
del->next = NULL;
del->prev = NULL;
}
//指定位置刪除
void Erase(Node *head, Node *pos)
{
if(head->next == NULL)
{
printf("連結串列為空,刪除失敗\n");
return ;
}
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
free(pos);
pos->next = NULL;
pos->prev = NULL;
}
執行結果