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 對於暴力解法,我們會將整個鍊錶分為 有序段 和 無序段 兩段...