資料結構之鍊錶 鍊錶實現及常用操作 C 篇

2021-09-23 23:37:48 字數 3541 閱讀 9271

單向鍊錶的節點包括:

資料域:用於儲存資料元素的值。

struct node;

雙向鍊錶的節點包括:

資料域:用於儲存資料元素的值。

struct dnode;

//p節點後插入值為i的節點

void insertnode(node *p, int i)

當需要刪除乙個節點p時,只需要將p的前乙個節點的next賦為p->next,但是由於是單向的,只知道p,無法知道p前乙個節點,所以需要轉換思路。將p下乙個的節點覆蓋到p節點即可,這樣就等效於將p刪除了。

void deletenode(node *p)
法一:反向遍歷鍊錶就類似於事先遍歷的節點後輸出,即「先進後出」,那麼可以將鍊錶遍歷存放於棧中,其後遍歷棧依次彈出棧節點,達到反向遍歷效果。

void printlinkedlistreversinglybystack(node *head)

while (!nodesstack.empty())

}//2.遞迴

void printlinkedlistreversinglyrecursively(node *head)

printf("%d\t", head->value);

}}

用slow和fast指標標記,slow每次走一步,fast每次走兩步,當fast到尾節點時,slow就相當於總長度的一半,即在中間節點。

//找出中間節點

node* findmidnode(node* head)

return slow;

}

用slow和fast指標標記,fast指標事先走k步,然後slow和fast同時走,當fast到達末節點時,slow在fast的前k個節點,即為倒數第k個節點。

//找出倒數第k個節點

node* findknode(node* head,int k)

temp2 =temp2->next;

}while (temp2->next != null&&temp2->next->next!=null)

return temp1;

}

題意即為將鍊錶反過來,即,原本為p1-p2-p3翻轉為p3-p2-p1。讀者需自行畫圖體會指標操作。

//翻轉鍊錶

node * reverselinkedlist(node* head,int k)

node* nxt = pnode->next;

pnode->next = pre;

pre=pnode;

pnode=nxt;

}return reversedhead;

}

如果兩個鍊錶相交,其形狀必為y形,而不可以能為x形,即兩條鍊錶必有相同的尾節點。首先,計算得到兩個鍊錶的長度:m,n,求得兩個鍊錶長度之差distance=|m-n|,讓較長得那個鍊錶事先走distance步,這樣,若是鍊錶相交得話,二者指標必相撞,相撞點即為相交點。

node* findcrosspoint(node* l1, node* l2)

} else

}while(temp1!=temp2&&temp1->next!=null&&temp2->next!=null)

if(temp1 == temp2)

return 0;

}

此題很有意思,具體詳細請參考:

判斷是否含有環:slow和fast,slow指標每次走一步,fast指標每次走兩步,若是鍊錶有環,fast必能追上slow(相撞),若fast走到null,則不含有環。

//判斷是否含有環

bool containloop(node* head)

node* slow = head;

node* fast = head;

while (slow!=fast&&fast->next!=null)

if (fast==null)

return true;

}

判斷環的長度:在相撞點處,slow和fast繼續走,當再次相撞時,slow走了length步,fast走了2*length步,length即為環得長度。

//獲得環的長度

int getlooplength(node* head)

node* slow = head;

node* fast = head;

while (slow!=fast&&fast->next!=null)

if (fast==null)

//slow和fast首次相遇後,slow和fast繼續走

//再次相遇時,即slow走了一圈,fast走了兩圈

int length = 0;

while (slow!=fast)

return length;

}

//獲得環的連線點

node* getjoinpoit(node* head)

node* slow = head;

node* fast = head;

while (slow!=fast&&fast->next!=null)

if (fast==null)

node* fromhead = head;

node* fromcrashpoint = slow;

while (fromcrashpoint!=fromhead)

return fromhead;

}

二叉樹和雙向鍊錶轉化指的是,二叉樹節點結構和雙向鍊錶的結構想類似,只不過二叉樹節點的節點儲存的兩個指標為左右子數,而雙向鍊錶儲存的是前後節點。題意為將二叉樹的某種遍歷轉化為鍊錶儲存。此題很明顯該用遞迴,讀者可以畫圖體會一下指標變化。

二叉樹節點或雙向鍊錶節點定義:

struct binarytreenode;
二叉樹的中序遍歷轉換為雙向鍊錶

binarytreenode* convertnode(binarytreenode* pnode, binarytreenode** plastnodeinlast)

binarytreenode *pcurrent = pnode;

if (pcurrent->left != null)

pcurrent->left = *plastnodeinlast;

if (*plastnodeinlast != null)

*plastnodeinlast = pcurrent;

if (pcurrent->right != null)

return null;

}binarytreenode* convertbttodll(binarytreenode* root)

return pheadoflist;

}

資料結構之鍊錶 鍊錶實現及常用操作 C 篇

單向鍊錶的節點包括 資料域 用於儲存資料元素的值。struct node 雙向鍊錶的節點包括 資料域 用於儲存資料元素的值。struct dnode p節點後插入值為i的節點 void insertnode node p,int i 當需要刪除乙個節點p時,只需要將p的前乙個節點的next賦為p n...

資料結構 表之煉表

頭插法建立 尾插法建立 顯示 銷毀 include include using namespace std typedef int elemtype typedef struct lnode linklist void createlinklistf linklist l,elemtype a,in...

常用資料結構 鍊錶

鍊錶應該是面試時被提及最頻繁的資料結構 下面是乙個往鍊錶末尾插入元素的操作 typedef struct node node 往列表的末尾新增乙個節點 node insert tail node head,int key else temp next new node new node next n...