資料結構4 線性表的鏈式儲存結構(2)

2021-09-10 01:15:31 字數 3884 閱讀 3059

單鏈表的題目:

1、單鏈表的反轉

思路:借助三個指標p1,p2,p3。讓p1=head;p2=p1->nect;p3=p2->next;之後將p2->next=p1;然後將p1,p2 ,p3順序後移,一直到p3為空就會將鍊錶反轉。(特殊情況陣列中只有沒有或者只有乙個節點時,直接返回就可以。)

void linklistreverse(linklist* head)

node* p1 = (*head);

node* p2 = p1->next;

node* p3 = p2->next;

p2->next = p1;

while (p3)

(*head)->next = null;

(*head) = p2;

}

2、尋找單鏈表中倒數第i個元素

思路:快慢指標,是塊指標比慢指標多走i步,然後兩個指標以相同的速度前進,當快指標走到鍊錶尾部時,慢指標的位置就是倒數第i個節點的位置(特殊處理鍊錶中不存在倒數第i個節點)。

node* backfindnode(linklist head, int i)

if (null == pfast||i <= 0)

while (pfast->next)

return pslot;

}

3、找出單鏈表的中間元素

思路:快慢指標,快指標和慢指標的其實位置都是鍊錶的頭,快指標每次比慢指標多走一步,當快指標走到鍊錶尾部時慢指標的位置就是鍊錶的中間位置。(當鍊表元素為偶數個時,返回靠前的節點)

node* findlinklistmid(linklist head)

node* pfast = head;

node* pslot = head;

while (pfast->next) }

return pslot;

}

5、兩個不交叉的有序鍊錶的排序

思路:從鍊錶2中依此取出元素,在鍊錶1中尋找比該元素大的節點的前乙個節點,將鍊錶2中的節點插入到鍊錶1中尋找的位置的後面。

會有兩中特殊的情況:

(1)當前鍊錶2中元素小於鍊錶1的頭,需要頭插。

(2)當前鍊錶2中的元素大於鍊錶1中元素的最後乙個,將2中剩餘元素直接插到鍊錶1的後面,結束。

注意,每次執行完插入操作後需要將鍊錶1中尋找的位置移動到剛才位置上。

linklist mergelinklist(linklist* head1, linklist* head2)

if (null == (*head2))

//(1)從2中取出第乙個節點(w)

//(2)在1中存在第乙個比此值的大的元素(s)

//(3)將此節點(w)插入到1中節點(s)的前面(迴圈2)

//如果到了1的鏈尾部,將2中剩餘元素全部插入到1的後面

node* p1 = (*head1);

node* pfront = null;//s的前乙個位置

node* tnode = null;//w

while ((*head2))

if (null == p1)

else if(null == pfront)

else

}return (*head1);

}

6、單鏈表交換任意兩個位置的元素。

思路:尋找需要交換元素的位置和需要交換元素的前乙個節點,將需要交換的兩個從鍊錶上拆下來,之後將這兩個元素交錯的插入剛才尋找到的前乙個節點的位置。(特殊處理:如果兩個節點的位置相鄰,這時較小的元素就會稱為較大(位置)元素的前驅節點,從鍊錶上拆下時就會時較大的元素的位置丟失,這是需要重新尋找)

void swaplinklist(linklist* head, int i, int j)

//找出兩個中位置較小的

int min = i < j ? i : j;

//找出兩個中位置較大的

int max = i < j ? j : i;

node* pmax = getprepos(*head,max);

//最後乙個無後繼

if (null == pmax||null==pmax->next)

node* max = pmax->next;

pmax->next = max->next;

node* pmin = getprepos(*head, min);

if (null == pmin&&i != 0)

node* min;

//較小的數為0,需要特殊處理

if (0!=min)

else

if (0 == min)

else

if (max - min == 1)

min->next = pmax->next;

pmax->next = min;

}

7、判斷單鏈表是否有環?如何找到環的「起始」節點,並計算環的長度?

思路:快慢指標,起始位置都是鍊錶的頭步,讓快指標比慢指標每次多走一步,如果快指標走到鍊錶的尾部,則無環,如果快指標和慢指標相遇就說明有環。當確定鍊錶中存在環時,將相遇的兩個指標的任意乙個重新置回到鍊錶的頭步,然後兩個指標以每次一步的速度移動,當兩個節點再次相遇時,所在的節點就是入環點。計算長度時,設定乙個整形變數初始化為0,讓乙個指標不動另乙個指標每次移動一步,就讓記錄長度的變數加1,當兩個節點再次相遇的時候,整形變數中記錄的長度就是,環的長度。

建立乙個有環的節點

void ringlinklist(linklist* head)

p->next = (*head)->next;

}

判斷是否又環,並計算入環點和環的長度。

bool judgelinklistring(linklist head)

node* pfast = head;

node* pslot = head;

while (pfast->next&&(pfast!=pslot||(pfast==head&&pslot==head))) }

if (null == pfast->next)

int i = 1;

pslot = pslot->next;

while (pfast != pslot)

pslot = head;

while (pfast != pslot)

printf("%d,i=%d\n", pfast->data,i);

return true;

}

8、單鏈表的排序

思路:插入排序,因為鍊錶並不支援隨機訪問,所以在操作上會比較麻煩。

/*

但這個演算法受限於單鏈表的一些特性會有些改動。

因為單鏈表是沒有前驅的,所以要和前面乙個相比就會比較麻煩。

所以我們可以每遇到乙個新節點,如果他的值比前個節點的值大,就不動。

否則就將這個節點從鍊錶上拆下,放到合適的位置。

*/void sortlinklist(linklist* head)

node* pfront = (*head);

//第乙個節點前無元素

node* phead = (*head)->next;

while (phead)

if (null == phead)

else if (pfront == (*head))

else

else

phead->next = head->next;

head->next = phead;

}//前驅的位置不會改變

phead = pfront->next;

} }}

資料結構 鏈式儲存線性表

鏈式儲存結構的線性表 簡稱為鍊錶 將採用一組位址任意的儲存單元存放線性表中的資料元素,鏈式結構的線性表不會按線性的邏輯順序來儲存資料元素,它需要在每乙個資料元素裡儲存乙個引用下乙個資料元素的引用。優點 插入 刪除元素快,充分利用計算機記憶體空間 缺點 查詢元素需要整體遍歷,空間開銷大 單鏈表 cre...

線性表的鏈式儲存 資料結構

為了表示每個資料元素與其直接後繼資料元素之間的邏輯關係,除了儲存本身的資訊之外,還需儲存乙個指示其直接後繼的資訊 即直接後繼的儲存位置 我們把儲存資料元素資訊的位置稱為資料域,把儲存其直接後繼資訊的位置稱為指標域。這兩部分組成資料元素的結點 node 頭結點頭結點是為了操作的統一和方便而設立的,放在...

資料結構 線性表之鏈式儲存結構

資料結構定義 common.h ifndef hi comm h define hi comm h include include include include define list init size 100 線性表儲存空間的初始分配量 define list increment 10 線性表...