面試題之雙向連結串列簡單詳述
雙向連結串列其實是單鏈表的改進,對單鏈表進行操作時,有時要對某個節點的直接前驅進行操作,又必須從表頭開始查詢。由於單鏈表每個節點只有一個直接後繼節點儲存地址的練域,因此運用單鏈表無法辦到,這樣就引出了一個既有儲存直接後繼節點地址的練域,又有儲存直接前驅節點地址的練域的上向連結串列節點結構。
(1)建立一個雙向連結串列
雙向連結串列的定義如下:
typedef struct DbNode
{
int data; //節點資料
DbNode *left; //前驅節點指標
DbNode *right; //後繼節點指標
}DbNode;
建立雙向連結串列(為了方便,這裡定義了3個函式)如下所示:
CreateNode()根據資料建立一個節點,返回新建立的節點。
CreateList()函式根據一個節點資料建立連結串列的表頭,返回表頭節點。
AppendNode()函式總在表尾插入新節點(其內部條用CreateNode()生成節點),返回表頭節點。
//根據資料建立節點 DbNode *CreateNode(int data) { DbNode *pNode = (DbNode *)malloc(sizeof(DbNode)); pNode->data = data; pNode->left = NULL; //建立新節點時, pNode->right = NULL; //讓前驅和後繼指標都為NULL return pNode; } //建立連結串列 DbNode *CreateList(int head) //引數給出表頭節點資料 { //表頭節點不作為存放有意義資料的節點 DbNode *pNode = (DbNode *)malloc(sizeof(DbNode)); pNode->data = head; pNode->left = NULL; pNode->right = NULL; return pNode; } //總是在表尾插入新節點,返回表頭節點 DbNode *AppendNode(DbNode *head, int data) { DbNode *node = CreateNode(data); DbNode *p = head; DbNode *q = NULL; while(NULL != p) { q = p; p = p->right; } q->right = node; node->left = q; return head; }
可以使用其中的CreateList和AppendNode來生成一個連結串列,下面是一個生成從節點0---9的雙向連結串列。
DbNode *head = CreateList(0);
for(int i=1; i<10; i++)
{
head = AppendNode(head, i);
}
上向連結串列的測長:
//雙向連結串列的測長 int GetLength(DbNode *head) { int count = 1; DbNode *pnode = NULL; if(NULL == head) { return 0; } pnode = head->right; while(NULL != pnode) { pnode = pnode->right; count++; } return count; }
雙向連結串列的列印:
//雙向連結串列的列印
void PrintList(DbNode *head)
{
DbNode *pnode = NULL;
if(NULL == head)
{
return;
}
pnode = head;
while(NULL != pnode)
{
printf("%d ", pnode->data);
pnode = pnode->right;
}
printf("\n");
}
雙向連結串列的節點查詢:
//雙向連結串列的節點查詢
DbNode *FindNode(DbNode *head, int data)
{ //data為將要查詢的節點的資料
DbNode *pnode = head;
if(NULL == head)
{
return NULL;
}
//找到資料或者到達連結串列末尾退出
while(NULL != pnode->right && pnode->data != data)
{
pnode = pnode->right;
}
if(NULL == pnode) //沒有找到
{
return NULL;
}
return pnode;
}
雙向連結串列的節點插入:
//雙向連結串列的節點插入
void InsertNode(DbNode *node, int data)
{
DbNode *newnode = CreateNode(data);
//DbNode *p = NULL;
if(NULL == node)
{
return ;
}
if(NULL == node->right) //node為最後一個節點
{
node->right = newnode;
newnode->left = node;
}
else
{ //node為中間節點
newnode->right = node->right; //newnode向右連線
node->right->left = newnode;
node->right = newnode; //newnode向左連線
newnode->left = node;
}
}
雙向連結串列的節點刪除:
//雙向連結串列的節點刪除
//刪除滿足指定條件的節點,返回表頭節點,節點不存在刪除失敗返回NULL
DbNode *DeleteNode(DbNode *head, int data)
{
DbNode *ptmp = head->right;
DbNode *pnode = FindNode(head, data);
if(NULL == pnode)
{
return NULL;
}
else if(NULL == pnode->left) //刪除第一個節點
{
head = pnode->right; //head指向第二個節點
//head = ptmp;
if(NULL != head)
{
head->left = NULL;
}
}
else if(NULL == pnode->right) //刪除最後一個節點
{
pnode->left->right = NULL;
//pnode->left = pnode->right = NULL;
}
else //刪除中間節點
{
pnode->left->right = pnode->right;
pnode->right->left = pnode->left;
}
free(pnode);
return head;
}
下面是測試的主函式:
int main()
{
DbNode *head = CreateList(0);
for(int i=1; i<10; i++)
{
head = AppendNode(head, i); //建立
}
int count = GetLength(head); //測長
printf("length = %d\n", count);
printf("print list..."); //列印
PrintList(head);
DbNode *FNode = FindNode(head, 7); //查詢
printf("find node data = %d\n", FNode->data);
printf("insert node data 888....\n");
InsertNode(FNode, 888); //插入
PrintList(head);
printf("Delete node....\n");
head = DeleteNode(head, 0); //刪除
PrintList(head);
return 0;
}
下面是執行結果:
length = 10
print list...0 1 2 3 4 5 6 7 8 9
find node data = 7
insert node data 888....
0 1 2 3 4 5 6 7 888 8 9
Delete node....
1 2 3 4 5 6 7 888 8 9
Press any key to continue
相關推薦
面試題之雙向連結串列簡單詳述
雙向連結串列其實是單鏈表的改進,對單鏈表進行操作時,有時要對某個節點的直接前驅進行操作,又必須從表頭開始查詢。由於單鏈表每個節點只有一個直接後繼節點儲存地址的練域,因此運用單鏈表無法辦到,這樣就引出了一個既有儲存直接後繼節點地址的練域,又有儲存直接前驅節點地
雙向連結串列簡單實現--資料結構與演算法紀錄片第一記
從這個月開始得準備春招的東西,所以打算重新學習資料結構與演算法,以後的部落格就以這個為主。 今天是線性結構中的雙向連結串列。 程式碼實現與測試: DoubleLinkNode: package linear.doublelink;/** * @Description: 連結串列節點結
資料結構-----------線性表(下篇)之雙向連結串列
//----------雙向連結串列的儲存結構------------ typedef struct DuLNode { ElemType date; struct DoLNode *prior; struct DoLNode *next; } DoLNode,*DoLinkList;
【面試題】求連結串列的環入口點
環入口點:我們設A是連結串列的起點,B是環的入口點,C是環內快慢指標的相遇點。兩個快慢指標定義為slow和fast. slow走的路程:A->B->C; fast走的路程:A->B->C->B->C; 2*(x+y)=x+y+z+y
資料結構與演算法(五)-線性表之雙向連結串列與雙向迴圈連結串列
前言:前面介紹了迴圈連結串列,雖然迴圈連結串列可以解決單鏈表每次遍歷只能從頭結點開始,但是對於查詢某一節點的上一節點,還是頗為複雜繁瑣,所以可以在結點中加入前一個節點的引用,即雙向連結串列 一、簡介 雙向連結串列:在連結串列中,每一個節點都有對上一個節點和下一個節點的引用或指標,即從一個節點出發可以有
劍指Offer.面試題18.刪除連結串列中重複的節點
在一個排序的連結串列中,存在重複的結點,請刪除該連結串列中重複的結點,重複的結點不保留,返回連結串列頭指標。 例如,連結串列1->2->3->3->4->4->5 處理後為 1->2->5 思路: 設定三個指標。
Java手寫LinkedList 應用資料結構之雙向連結串列
作為Java程式設計師,紮實的資料結構演算法能力是必須的 LinkedList理解的最好方式是,自己手動實現它 ArrayList和LinkedList是順序儲存結構和鏈式儲存結構的表在java語言中的實現. ArrayList提供了一種可增長陣
C++ 雙向連結串列簡單實現通訊錄
#include<iostream> #include<fstream> #include <stdlib.h> #include<string> using namespace std; typedef struct Director
【劍指Offer學習】【面試題56:連結串列中環的入口結點】
題目:一個連結串列中包含環,如何找出環的入口結點? 解題思路 可以用兩個指標來解決這個問題。先定義兩個指標P1和P2指向連結串列的頭結點。如果連結串列中環有n個結點,指標P1在連結串列上向前移動n步,然後兩個指標以相同的速度向前移動。當第二個指標
1.6 python資料結構之雙向連結串列/迴圈連結串列——以OrderedDict資料結構為例
在連結串列這一部分的最後,我們以python中十分強大的collections包中的OrderedDict為例,看一下雙向迴圈列表的功能實現。 OrderedDict 它提供了有序的dict結構,因此他不是常規的雜湊雜湊表,為了保證儲存物件有序,它用連結串列實現了這一功能,
C++演算法之雙向連結串列的程式碼
工作閒暇時間,把程式碼過程較好的程式碼片段收藏起來,下邊資料是關於C++演算法之雙向連結串列的程式碼,應該是對各朋友有些用處。 typedef struct _DOUBLE_LINK_NODE { int data; }DOUBLE_LINK_NODE; 複製程式碼(2
劍指Offer面試題24 反轉連結串列
輸入一個連結串列,按連結串列值從尾到頭的順序返回一個ArrayList。 牛客網提交程式碼: /** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x)
C語言之雙向連結串列
為了克服單向性的缺點,雙向連結串列得到應用。 typedef struct link { int data; struct link* prev; //比起單向連結串列,多了指向前個節點的指標 struct link* next; }link,*link_str;
劍指Offer面試題:14.連結串列的倒數第k個節點
PS:這是一道出境率極高的題目,記得去年參加校園招聘時我看到了3次,但是每次寫的都不完善。 一、題目:連結串列的倒數第k個節點 題目:輸入一個連結串列,輸出該連結串列中倒數第k個結點。為了符合大多數人的習慣,本題從1開始計數,即連結串列的尾結點是倒數第1個結點。例如一個連結串列有6個結點,從頭結點開始
劍指Offer面試題56:連結串列中環的入口節點 Java實現
/************************************************************** * Copyright (c) 2016, * All rights reserved. * 版 本 號:v1.0
資料結構之雙向連結串列(JAVA實現)
歡迎轉載,請附出處: http://blog.csdn.net/as02446418/article/details/47114711 最近重新複習了一些基礎的資料結構,發覺自己好多已經淡忘了,索性重新撿起來以前的知識,今天筆者回顧了一下連結串列的知識,用J
【面試題】 求連結串列倒數第K個節點
題目:輸入一個連結串列輸出連結串列中的第K個節點,(計數從1開始),連結串列節點定義如下: //定義結構 struct ListNode { ListNode() :_next(NULL) ,_data(0) {} ListNode *_next; int
資料結構學習之雙向連結串列結構
注:本文的主要目的是為了記錄自己的學習過程,也方便與大家做交流。轉載請註明來自: 在前面總結的單向連結串列結構的基礎上,現在開始著手實踐實踐雙向連結串列結構,如果充分理解了單向連結串列資料結構,那對雙向連結串列結構的理解也就不再困難,換個角度而言,雙向連
一步一步寫演算法(之雙向連結串列)
【 宣告:版權所有,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】 前面的部落格我們介紹了單向連結串列。那麼我們今天介紹的雙向連結串列,顧名思義,就是資料本身具備了左邊和右邊的雙向指標。雙向連結串列相比較單向連結串列,主要有下
面試題56:連結串列中環的入口節點
題目:一個連結串列中包含環,請找出該連結串列的環的入口結點。 這道題藉助於前面的連結串列的倒數第K個節點的思想,考慮快慢指標。考慮當知道了連結串列的環中所含的節點數目,用一個快指標