- 由於單鏈表中無法獲取當前節點的前一節點,因此在刪除時必須要能獲取其前驅節點。
- 檢查單鏈表是否存在環:設定一快一慢兩個節點指針,快指針一次進兩步,慢指針一次進一步。如果單鏈表存在環,那麼快指針必定會追上慢指針。否則,快指針先到鏈表末尾。如果進一步需要判斷環入口,則繼續將慢指針重置到鏈表頭,然後和慢指針一樣,每次前進一步,再次重合的點即爲環的入口。注意該方法的結果對快慢指針的起始位置相當敏感,必須統一設定爲單鏈表的頭結點,否則會出錯。
- 獲取單鏈表倒數第K個節點有兩種算法:常規算法是按照倒數第K個節點等於順序第N-K+1個節點(其中N代表單鏈表的長度),所以先求出單鏈表的總長度N然後順序遍歷找出第N-K+1個節點即可;第二種算法是由於單鏈表尾節點與倒數第K節點的距離是確定的,因此當兩個相距爲K的節點中的一個移動到單鏈表的結尾時,另一節點必定指向倒數第K個節點,因此算法設計是首先從鏈表頭開始順序找出第K個節點A,然後定義另一節點B,二者同時移動,當A到達單鏈表的結尾時,B同時到達倒數第K個節點。注意K值是從1開始的。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _node node;
typedef node* mList;
struct _node{
node* next;
int data;
};
mList CreateList()
{
mList header = (mList)malloc(sizeof(node));
header->next = NULL;
header->data = 0;
return header;
}
node* FindNode(mList list,int data)
{
node* index_node = list;
if (index_node->data == data)
return NULL;
while(index_node->next->next != NULL){
if (index_node->next->data == data)
return index_node;
else
index_node = index_node->next;
}
return index_node;
}
mList InsertNode(mList list,int pos, int data){
node* position = FindNode(list,pos);
node* new_node = (node*)malloc(sizeof(node));
if (new_node == NULL){
printf ("Out of Resources !!!\n");
}
if (position == NULL){
new_node->next = NULL;
list->next = new_node;
new_node->data = data;
}
else{
new_node->data = data;
new_node->next = position->next->next;
position->next->next = new_node;
}
return list;
}
mList DeleteNode(mList list, int pos)
{
node* position=FindNode(list,pos);
if (position == NULL)
return list->next;
else{
position->next = position->next->next;
return list;
}
}
node* FindLoop(mList list)
{
node* fast_node = list;
node* slow_node = list;
while ((fast_node->next != NULL) && (fast_node->next->next != NULL)){
printf("fast_node: %d, slow_node: %d\n",fast_node->data,slow_node->data);
fast_node = fast_node->next->next;
slow_node = slow_node->next;
if (fast_node == slow_node){
fast_node = list;
while(fast_node != slow_node){
fast_node = fast_node->next;
slow_node = slow_node->next;
}
return fast_node;
}
}
return NULL;
}
node* GetKth(mList list, unsigned int k)
{
unsigned int index = 1;
node* node_index = list;
node* result_node = list;
while(index++ < k)
node_index = node_index->next;
while(node_index->next != NULL){
result_node = result_node->next;
node_index = node_index->next;
}
return result_node;
}
mList Reverse(mList list)
{
}
void PrintList(mList list)
{
mList index_list = list;
while(index_list->next != NULL){
printf ("%d -> ",index_list->data);
index_list = index_list->next;
}
printf ("%d end \n",index_list->data);
}
node* FindLastNode(mList list)
{
mList temp_list = list;
while (temp_list->next != NULL)
temp_list = temp_list->next;
return temp_list;
}
int main(int argc, char *argv[]) {
int a[]={1,2,3,4,5,6,7,8,9};
int loop[]={100,101,102,103};
char i=0;
node* loop_entrance = NULL;
unsigned int k=1;
node* kth_node = NULL;// the Kth node from the back of the list.
// create a loop list.
mList loop_list = CreateList();
mList header = loop_list;
loop_list->data = loop[0];
for (i=1; i<(sizeof(loop)/sizeof(loop[0])); i++)
{
node* temp_node = (node*) malloc(sizeof(node));
temp_node->data = loop[i];
loop_list->next = temp_node;
loop_list = loop_list->next;
}
loop_list->next = header;
mList list = CreateList();
list->data = a[0];
for (i=0; i<(sizeof(a)/sizeof(a[0]))-1; i++)
list = InsertNode(list,a[i],a[i+1]);
node* last_node = FindLastNode(list);
//last_node->next = header;
// handle the list.
PrintList(list);
printf("\n");
list = DeleteNode(list,a[8]);
if ((loop_entrance = FindLoop(list)) == NULL)
printf("there is no loop in this list \n");
else
printf("find a loop in this list, its entrance is %d \n",loop_entrance->data);
k=3;
kth_node = GetKth(list,k);
printf("the %dth node from the back of the list is:%d \n",k,kth_node->data);
PrintList(list);
return 0;
}