基礎演算法模板之鍊錶 排序

2021-07-05 03:07:23 字數 3462 閱讀 6887

1.鍊錶

操作:建表、反轉、合併兩個有序的鍊錶,其他簡單的刪除節點、插入節點就不說了

#include

#include

using namespace std;  

struct listnode  

;  //建表  

void createlist(listnode **phead)  

//鍊錶非空  

else   

pnode->next = pnew;  

}  }  

}  //反轉  

listnode *reverselist(listnode *phead)  

return pnewhead;  

}  //兩個遞增有序鍊錶的合併  

listnode *merge(listnode *phead1, listnode *phead2)  

else   

//實際維護3個指標,p1,p2,pcurrent  

//pcurrent維護合併後的新鍊錶  

listnode *pcurrent = head;  

while (p1 != null && p2 != null)  

else   

}  //將鍊錶長度更長者,鏈結到pcurrent尾端  

if (p1 != null)  

pcurrent->next = p1;  

if (p2 != null)  

pcurrent->next = p2;  

return head;  

}  void printlist(listnode *phead)  

printf("\n");  

}  int main()  

2.排序(七大排序演算法)

可先看下各種排序演算法的總結與比較:

交換排序:基本思想是:兩兩比較待排序的元素,發現倒序即交換。包含氣泡排序、快速排序。

氣泡排序:

每趟比較得到乙個最小(或最大)的數,每趟比較n - i 次,最多經過n-1趟比較。具體看**。

與待排序陣列的初始序列有關。最少只比較一趟,比較n-1次。

//兩種排序的方向:從下往上、從上往下  

#include

#include

using namespace std;  

void bubblesort1(int a, int n)  

}  }  void bubblesort2(int a, int n)  

}  }  int main()  

;  //bubblesort1(a,9);  

bubblesort1(a,9);  

for (int i = 0; i < 9; i++)  

cout<

using namespace std;  

void partition(int a, int s, int t, int &cutpoint)  

while (i < j && a[i] < x)i++;  

if (i < j)  

}  a[i] = x;  

cp = i;  

}  void quicksort(int a, int s, int t)  

}  int main()  

;  quicksort(a,0,6);  

for (int i = 0;i < 7; i++)  

else   

}  while (index1 <= mid)  

while (index2 <= last)  

for (int i = 0; i < k; i++)  

}  //先遞迴的分解數列,再合併數列,完成整個歸併排序  

void mergesort(int a, int first, int last, int temp)  

}  int temp[10];  

int main()  

;  mergesort(a,0,9,temp);  

for (int i = 0; i < 10; i++)  

a[j+1] = temp;  

}  }  

void insertionsort1(int a, int n)  

a[j+1] = a[0];  

}  }  

int main()  

;  int b[5]=;  

insertionsort1(a,10);  

insertionsort(b,5);  

int i;  

for (i = 1; i < 10; i++)  

\mathcal(n^2)

2^k - 1

\mathcal(n^)

2^i 3^j

\mathcal( n\log^2 n )

已知的最好步長序列是由sedgewick提出的 (1, 5, 19, 41, 109,...),該序列的項來自 9 * 4^i - 9 * 2^i + 1 和 4^i - 3 * 2^i + 1 這兩個算式[1].這項研究也表明「比較在希爾排序中是最主要的操作,而不是交換。」用這樣步長序列的希爾排序比插入排序和堆排序都要快,甚至在小陣列中比快速排序還快,但是在涉及大量資料時希爾排序還是比快速排序慢。

另乙個在大陣列中表現優異的步長序列是(斐波那契數列除去0和1將剩餘的數以**分割槽比的兩倍的冪進行運算得到的數列):(1, 9, 34, 182, 836, 4025, 19001, 90358, 428481, 2034035, 9651787, 45806244, 217378076, 1031612713, …)[2]

**:void shellsort(int a, int length)  

a[j+d] = temp;  

}  d /= 2;  

}  }  

希爾排序時間效能的分析是乙個複雜的問題,和取步長相關。取半步長的方法的時間複雜度為o(n*logn).

更詳細講解可參看:

選擇排序:

選擇排序的基本思想:在每一趟排序中,在待排序子表中選出關鍵字最小或最大的元素放在其最終的位置。選擇排序包含直接選擇排序、堆排序。

直接選擇排序:

直接選擇排序的思路,和直接插入排序不同的是,更多是站在位置的角度來思考,找出最終在該位置上的元素。

void selectionsort(int a, int n)  

}  //若最小的數就是當前的數那麼不交換,否則交換  

if (min != i)  

}  }  直接選擇排序很直觀,時間複雜度為o(n^2)。造成時間複雜度較大的原因是排序過程中可能存在多次的重複比較。

堆排序:

堆排序是對直接選擇排序演算法的改進,是利用堆的性質來進行的一種排序。

總結:各種排序有各自的特點,別忘了回過頭看看,各種排序演算法的總結與比較:

強烈推薦各種排序演算法的動態演示

to be continued !

鍊錶之排序鍊錶

148.排序鍊錶 力扣 leetcode leetcode cn.com 題目要求n logn 所以這邊考慮歸併排序 先分,再合,合的話就是合併兩個有序鍊錶,和合併兩個有序陣列一樣簡單 class solution listnode merge listnode l1,listnode l2 ptr...

演算法基礎 陣列 鍊錶 選擇排序

1 說說記憶體的工作原理?1 記憶體 就像很多抽屜的集合體,每個抽屜都有位址,fe0ffeeb是乙個記憶體單元的位址 2 將資料儲存到記憶體時,請求計算機提供空間,計算機給你乙個儲存位址。需要儲存多項資料時,有兩種儲存方式 陣列 鍊錶。2 說說陣列的原理?4個人去看電影,以陣列的形式將4個人儲存在座...

鍊錶排序演算法

1 題目 對亂序的鍊錶進行排序,要求空間複雜度為常數。leetcode 148 中等 輸入 4 2 1 3 輸出 1 2 3 4 輸入 1 5 3 4 0 輸出 1 0 3 4 5 2 思路 對於這題我有兩種解法,一種是時間複雜度o n2 對於暴力解法,我們會將整個鍊錶分為 有序段 和 無序段 兩段...