順序單鏈表歸併排序-騰訊筆試題
對單鏈表進行歸併排序,單鏈表與陣列相比只能順序訪問每個元素,因此在使用二路歸併排序時關鍵在於找到連結串列的中間結點將連結串列一分為二:可以利用一個步長為2的指標和一個步長為1的指標同時遍歷單鏈表,當步長為2的指標指向連結串列最後一個結點或者最後一個結點的下一個結點時,步長為1的指標即指向連結串列的中間結點。然後是兩個有序單鏈表的合併問題。時間複雜度為O(N*logN),空間複雜度為O(1)。
//mergesort for LinkList
#include
#include
#include
using namespace std;
typedef struct Node {
int data;
struct Node* next;
} LNode, *LinkList;
Node* getMiddle(LinkList L) {//無頭結點連結串列
LNode *mid, *midl, *p;
midl = NULL, p = mid = L;
while (p != NULL && p->next != NULL) {//利用快慢指標找連結串列的`中間位置並將連結串列1分為2
p = p->next->next;
midl = mid;
mid = mid->next;
}
midl->next = NULL;//將連結串列1分2
return mid;
}
void printList(LinkList L) {
LNode *p;
p = L;
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;;
}
void Merge(LinkList &La, LinkList Lb) {//將兩個有序連結串列La和Lb合併成一個有序連結串列La
LNode *pa = La, *pb = Lb;
LinkList Lc = NULL;
LNode *q = NULL;
if (pa->data <= pb->data) {
Lc = q = pa;
pa = pa->next;
}
else {
Lc = q = pb;
pb = pb->next;
}
while (pa != NULL && pb != NULL) {
if (pa->data <= pb->data) {
q->next = pa, pa = pa->next, q = q->next;
}
else {
q->next = pb, pb = pb->next, q = q->next;
}
}
if (pa == NULL) q->next = pb;
else if (pb == NULL) q->next = pa;
La = Lc;//La重新指向合併後的連結串列
}
void MergeSort(LinkList &L) {//注意引用的使用
if (L == NULL || L->next == NULL) return;//當連結串列長度小於等於1時即不用再分
LinkList La, Lb;
Lb = getMiddle(L);
La = L;
MergeSort(La);
MergeSort(Lb);
Merge(La, Lb);
L = La;//返回的結果代回
}
void DestroyList(LinkList &L) {
LNode *p, *q;
p = q = L;
while (p != NULL) {
q = q->next;
free(p);
p = q;
}
}
int main() {
int len = 10, i;
LinkList L;
LNode *p;
if ((L = (LinkList)malloc(sizeof(LNode))) == NULL) {
cerr << "Error in allocate memory!" << endl;
return -1;
}
srand(time(NULL));
L->data = rand() mod 1000; L->next = NULL;
for (i = 1; i < len; i++) {
if ((p = (LNode*)malloc(sizeof(LNode))) == NULL) {
cerr << "Error in allocate memory!" << endl;
DestroyList(L);
return -1;
}
p->data = rand() mod 1000;
p->next = L->next;
L->next = p;//頭插
}
cout << "The list before sorting:" << endl;
printList(L);
MergeSort(L);
cout << " The list after sorting:" << endl;
printList(L);
DestroyList(L);
【順序單鏈表歸併排序-騰訊筆試題】相關文章: