忘記什麼時候做的筆試題了。記憶力差沒辦法。
一看到這倒題目,下意識的想到的解決方案便是首先迴圈遍歷鍊錶獲得鍊錶長度len,然後再次迴圈遍歷鍊錶查詢len/2處的中間節點。在這種情況下,其時間複雜度由兩次迴圈決定:o(l+l/2)=o(3l/2)。
儘管這種思路也能解決問題,但也許存在更好的方法。上次我們談到利用雙指標來尋找鍊錶中倒數第n個元素結點,現在我們同樣也可以利用雙指標來查詢中間節點:
設定兩個指標*search,*mid,初始時,都指向頭結點。其中*search的移動速度為*mid的兩倍。模擬物理中的勻速運動,相同時間內,*search經過的結點應該是*mid結點個數的2倍,也就說,當*search結點到達鍊錶終點時,*mid在鍊錶中間結點處。
下面放上**實現:
#include#include#includetypedef int elemtype;
typedef struct nodenode;
int insertlast(node** pnode, elemtype ele);
//1、初始化鍊錶,未帶頭結點
void init(node** pnode)
void init_n(node** pnode)
printf("------>鍊錶初始化<------\n");
(*pnode)->next = null;
}//1、建立鍊錶
node* create(node* phead)
memset(p1, 0, sizeof(node));
printf("輸入節點值(非正數結束):");
scanf_s("%d", &p1->element);//輸入新節點
p1->next = null;
while (p1->element > 0)
else
p2 = p1;//重新讓p2做尾節點
p1 = (node*)malloc(sizeof(node));
if (p1 == null || p2 == null)
memset(p1, 0, sizeof(node));
printf("輸入節點值(非正數結束):");
scanf_s("%d", &p1->element);
p1->next = null;
} printf("鍊錶建立成功\n");
return phead;
}//列印鍊錶,不帶頭結點的情況
void print(node* phead)
else
printf("\n"); }}
//鍊錶長度
int size(node* phead)
printf("鍊錶長度%d\n", size);
return size;
}//獲取指定位置的元素
elemtype get(node* phead, int pos)
if (phead == null)
while (phead != null)
phead = phead->next;
} if (i < pos)
return phead->element;
}//插入頭節點
int inserthead(node** pnode, elemtype ele)
//插入尾節點
int insertlast(node** pnode, elemtype ele)
phead->next = pinsert;
*pnode = ptmp;
printf("向表尾插入元素:%d\n",ele);
return 1;
}//在指定位置插入元素
int insertmid(node** pnode, int pos, elemtype ele)
if (pos < 1)
while (phead != null)
phead = phead->next;
} if (i < pos)
nhead = phead->next;//儲存後乙個節點
pinsert->next = phead->next;
phead->next = pinsert;
printf("插入中間節點\n");
return 1;
}//刪除指定位置元素
int deletemidele(node** pnode, int pos)
while (phead != null)
phead = phead->next;
} de = phead->next;
phead->next=de->next;
printf("刪除元素成功\n");
return 1;
}//刪除第乙個節點
int delhead(node** pnode)
if (phead->next == null)
phead = phead->next;//設定原先頭節點的下乙個節點為頭節點
*pnode = phead;
printf("刪除頭節點成功\n");
return 1;
}//刪除尾節點
int dellast(node** pnode)
while (phead->next!= null)
printf("刪除尾節點\n");
free(phead);
predel->next = null;
return 1;
}//一次遍歷查詢倒數第n個元素
int getnodefromback(node* phead, int n, elemtype *e)
if (p->next == null&&i < n - 1)
node* p2 = phead;
while (p != null)
*e = p2->element;
printf("倒數第%d個元素是:%d\n", n, *e);
return 1;
}//查詢中間元素結點
int getmidnode(node* phead, elemtype *e)
else
} *e = mid->element;
return 1;
}void main()
總結:涉及單鏈表優化的問題,首先要考慮是否可以用雙指標解決。
尋找單鏈表的中間結點
如何尋找單鏈表的中間結點?這裡介紹兩種方法。該方法的思路為 1 先求解單鏈表的長度 length 2 然後遍歷 length 2 的距離即可查詢到單鏈表的中間結點。具體實現 public node findmidele node head return tmp 該方法的缺點 需要遍歷兩次鍊錶,即第一...
查詢單鏈表中間元素
查詢單鏈表中間元素 include using namespace std struct linknode class linklist linklist void insertvalue int nvalue void reverse void reverse2 linknode findlast...
取得單鏈表中間元素
配套的單鏈表在另一篇部落格。核心問題就是下面的那個while判斷條件,和最下面的奇數鍊錶和偶數鍊錶的問題。然後是判斷單鏈表的元素個數是奇數還是偶數的問題,觀察 畫的表。當元素個數為奇數的時候,first停止時,second位置正好就是中間的位置,問題是元素個數為偶數的時候,first停止時,中間有兩...