大话数据结构文摘
第1章 數據結構緒論
程序設計=數據結構+算法
數據結構:是相互之間存在一種或多種特定關系的數據元素的集合
1.邏輯結構 :是指數據對象中數據元素之間的相互關系
a:集合結構 ?b:線性結構 ?c:樹形結構 ?d:圖形結構
2.物理結構:在計算機中的存儲形式
a: 循序存儲 ?b: 鏈式存儲
第2章 算法
算法: 是解決特定問題求解步驟的描述,在計算機中表現為指令的有限序列,并且每條指令表示一個或多個操作
特性:1.輸入輸出 2.有窮性 3.確定性 4.可行性
算法設計的要求:
1.正確性 2.可讀性 3.健壯性 4.時間效率高和存儲量低
算法的時間復雜度:
推導大O階方法:
1. 用常數1取代運行時間中的所有加法常數
2.在修改后的運行次數函數中,只保留最高階項
3.如果最高價項存在且不是1,則去除與這個項相乘的常數
常數階:O(1) ?; ? 線性階: ? O(n) ; ?對數階:O(logn) ; ?平方階: O(n2)
O(1) ?< ? O(logn) ?< ?O(n) ? < ? O(nlogn) ?< O(n2) ? < ?O(n3) ? < ? O(2n) ?< O(n!) ?< ?O(nn)
第3章 線性表
線性表:零個或多個數據元素的有限序列
1.順序存儲結構:
| 優點 | 缺點 |
| 無須為表示表中元素之間的邏輯關系而增加額外的存儲空間 | 插入和刪除操作需要移動大量元素 |
| 可以快速地存取表中任一位置的元素 | 當線性表長度變化較大時難以確定存儲空間的容量 |
| ? | 造成存儲空間的“碎片” |
?
2.鏈式存儲結構:
單鏈表:
單鏈表與順序存儲結構作比較:
| 存儲分配方式 | 時間性能 | 空間性能 |
| 順序存儲用一段連續的存儲單元依次存儲線性表的數據元素 | 查找:順序:O(1),單鏈:O(n) | 差 |
| 單鏈表采用鏈式存儲結構,用一組任意的存儲單元存放線性表的元素 | 插入刪除:順序:O(n),單鏈:O(1) | 好 |
?
靜態鏈表:用數組描述的鏈表
| 優點 | 缺點 |
| 在插入和刪除操作時,只需要修改游標,不需要移動元素 | 沒有解決連續存儲分配帶來的表長難以確定的問題 |
| ? | 失去了順序存儲結構隨機存取的特性 |
?
循環鏈表:將單鏈表中終端結點的指針由空指針改為指向頭結點,就使整個單鏈表形成一個環,這種頭尾相接的單鏈表稱為單循環鏈表,簡稱循環鏈表
雙向鏈表:在單鏈表的每個結點中,再設置一個指向其前驅結點的指針域
第4章 棧與隊列
棧:限定僅在表尾進行插入和刪除操作的線性表
后進先出,(3種元素,就有5種可能的出棧順序)
棧的順序存儲結構,進棧,出棧,O(1)
兩棧共享空間
棧的鏈式存儲結構,0(1)
斐波那契數列:
0 ,當n=0
1,當n=1
F(n) = F(n-1) + F(n-2),當n>1
四則運算表達式求值:后綴表達法,(逆波蘭)
-----------------------------------------------------------------
隊列:只允許在一端進行插入操作,而在另一端進行刪除操作的線性表
先進先出
第5章 串
由零個或多個字符組成的有限序列,字符串
樸素的模糊匹配算法:最好:O(n+m),n為主串長度,m為子串長度,最差:O((n-m+1)*m)
KMP模式匹配算法:O(n+m)
第6章 樹
完全二叉樹
二叉樹遍歷方法:1.前序遍歷 2.中序遍歷 3.后序遍歷 4.層序遍歷?
線索二叉樹
赫夫曼樹
第7章 圖?
第8章 查找
1.靜態查找:
順序查找:O(n)
/* 無哨兵順序查找,a為數組,n為要查找的數組個數,key為要查找的關鍵字 */ int Sequential_Search(int *a,int n,int key) {int i;for(i=1;i<=n;i++){if (a[i]==key)return i;}return 0; } /* 有哨兵順序查找 */ int Sequential_Search2(int *a,int n,int key) {int i;a[0]=key;i=n;while(a[i]!=key){i--;}return i; }有序表查找:
二分查找:O(logn)/* 折半查找 */
遞歸算法
static int BinarySearch2(int[] a, int value, int low, int high){int mid = (low + high) / 2;if (a[mid] == value)return mid;else if (a[mid] > value)return BinarySearch2(a, value, low, mid);else if (a[mid] < value)return BinarySearch2(a, value, mid, high);else return 0;}非遞歸算法
int Binary_Search(int *a,int n,int key) {int low,high,mid;low=1; /* 定義最低下標為記錄首位 */high=n; /* 定義最高下標為記錄末位 */while(low<=high){mid=(low+high)/2; /* 折半 */if (key<a[mid]) /* 若查找值比中值小 */high=mid-1; /* 最高下標調整到中位下標小一位 */else if (key>a[mid])/* 若查找值比中值大 */low=mid+1; /* 最低下標調整到中位下標大一位 */else{return mid; /* 若相等則說明mid即為查找到的位置 */}}return 0; }c#版本:
static int Test(int[] a,int x)
{
int low = 0, high = a.Length-1, mid;
while (low <= high)
{
mid = (low + high) / 2;
if (x < a[mid])
{
high = mid - 1;
}
else if (x > a[mid])
{
low = mid + 1;
}
else
{
return mid;
}
}
return 0;
}
插值查找:O(logn)
/* 插值查找 */ int Interpolation_Search(int *a,int n,int key) {int low,high,mid;low=1; /* 定義最低下標為記錄首位 */high=n; /* 定義最高下標為記錄末位 */while(low<=high){mid=low+ (high-low)*(key-a[low])/(a[high]-a[low]); /* 插值 */if (key<a[mid]) /* 若查找值比插值小 */high=mid-1; /* 最高下標調整到插值下標小一位 */else if (key>a[mid])/* 若查找值比插值大 */low=mid+1; /* 最低下標調整到插值下標大一位 */elsereturn mid; /* 若相等則說明mid即為查找到的位置 */}return 0; }斐波那契查找
線性索引查找:
稠密索引,在線性索引中,將數據項的每個記錄對應一個索引項。
分塊索引,分塊有序的數據集,將每塊對應一個索引項。
倒排索引,由屬性值來確定記錄的位置。
2.動態查找:查找時需要插入和刪除
二叉排序樹,O(logn)-O(n)
平衡二叉樹(AVL樹),(O(logn))
B樹(多路查找樹),
2-3樹,
2-3-4樹,
B+樹
散列表查找
直接定址法,數學分析法,平方取中法,折疊法,除留余數法,隨機數法
處理散列沖突的方法:1.開放定址法,2再散列函數法,3.鏈地址法,4,公共溢出區法
第9章 排序
| 排序 | |||||||
| 插入排序類 | 選擇排序類 | 交換排序類 | 歸并排序類 | ||||
| 直接插入排序 | 希爾排序 | 簡單選擇排序 | 堆排序 | 冒泡排序 | 快速排序 | 歸并排序 | |
| 排序方法 | 平均情況 | 最好情況 | 最壞情況 | 輔助空間 | 穩定性 |
| ?冒泡排序 | ?O(n2) | ?O(n) | ?O(n2) | ?O(1) | 穩定 |
| ?簡單選擇排序 | ?O(n2) | ?O(n2) | ?O(n2) | ?O(1) | 穩定? |
| ?直接插入排序 | ?O(n2) | ?O(n) | ?O(n2) | ?O(1) | 穩定? |
| ?希爾排序 | ?O(nlogn)-O(n2) | ?O(n1.3) | ?O(n2) | ?O(1) | 不穩定? |
| ?堆排序 | ?O(nlogn) | ?O(nlogn) | ?O(nlogn) | ?O(1) | 不穩定? |
| ?歸并排序 | ?O(nlogn) | ?O(nlogn) | ?O(nlogn) | ?O(n) | 穩定? |
| ?快速排序 | ?O(nlogn) | ?O(nlogn) | ?O(n2) | ?O(nlogn)-O(n2) | 不穩定? |
?
假設含有n個記錄的序列為{r1,r2,.....rn},其對應的關鍵字分別為{k1,k2...kn},
需確定1,2,。。。N的一種排列p1,p2,...pn,使其相應的關鍵字滿足kp1<=kp2...<=kpn
非遞減(或非遞增)關系,即使得序列成為一個按關鍵字有序的序列{rp1,rp2...rpn},這樣的操作叫做排序
排序的穩定性:
假設ki=kj,且在排序前的序列中ri領先于rj,如果排序后仍然領先,則是穩定的,反之是不穩定的。
內排序與外排序:
內排序所有記錄放在內存中,外排序需要在內外存之間多次交換數據才能進行。
冒泡排序:
int[] array = { };void swap(int[] array, int i, int j){int temp = array[i];array[i] = array[j];array[j] = temp;}///冒泡排序1///void bubblesort1(int[] array){for (int i = 0; i < array.Length;i++ ){for (int j = i + 1; j < array.Length;j++ ){if (array[i] > array [j]){swap(array, i, j);}}}}///冒泡排序2///void bubblesort2(int[] array){for (int i = 0; i < array.Length; i++){for (int j = array.Length-1; j >=i; j--){if (array[i] > array[j]){swap(array, i, j);}}}}///冒泡排序3///void bubblesort3(int[] array){bool flag = true;for (int i = 0; i < array.Length && flag; i++){flag = false;for (int j = array.Length - 1; j >= i; j--){if (array[i] > array[j]){swap(array, i, j);flag = true;}}}}冒泡排序時間復雜度O(n2)
?簡單選擇排序:
簡單選擇排序//void selectSort(int[] array){int i,j,min;for (i = 0; i < array.Length-1; i++ ){min = i;for (j = i + 1; j <= array.Length-1; j++){if (array[min] > array[j]){min = j;}}if (i != min){swap(array,i,min);}}}簡單選擇排序時間復雜度O(n2)
?直接插入排序: 撲克牌
/// <summary>/// //直接插入排序////// </summary>void insertSort(int[] array){int t,i, j;for (i = 1; i < array.Length; i++){if (array[i] < array[i - 1]){t = array[i];for (j = i - 1; j >= 0; j--){array[j + 1] = array[j];}array[j + 1] = t;}}}直接插入排序時間復雜度O(n2)
??希爾排序:
static void shellSort(int[] array){int i, j, temp;int increment = array.Length;do{increment = increment / 3 + 1;for (i = increment; i < array.Length; i++){if (array[i] < array[i - increment]){temp = array[i];for (j = i - increment; j >= 0 && temp < array[j]; j -= increment){array[j + increment] = array[j];}array[j + increment] = temp;}}}while (increment > 1);}希爾排序時間復雜度O(n3/2)
不穩定
堆排序:
堆是具有下列性質的完全二叉樹:
每個結點的值都大于或等于其左右孩子結點的值,稱為大頂堆;
每個結點的值都小于或等于其左右孩子結點的值,稱為小頂堆;
static void HeapSort(int[] array){int i;for (i = array.Length / 2 - 1; i >= 0; i--)HeapAdjust(array, i, array.Length - 1);for (i = array.Length - 1; i >= 1; i--){swap(array, 0, i);HeapAdjust(array, 0, i - 1);}}static void HeapAdjust(int[] array, int i, int m){int temp, j;temp = array[i];for (j = 2 * i; j <= m; j *= 2){if (j < m && array[j] < array[j + 1])++j;if (temp >= array[j])break;array[i] = array[j];i = j;}array[i] = temp;}時間復雜度O(nlogn)
不穩定
歸并排序:
時間復雜度O(nlogn)
穩定
快速排序:
原始版本static void QuickSort(int[] array, int low, int high){int pivot;if(low < high){pivot = Partition(array,low,high);QuickSort(array, low, pivot - 1);QuickSort(array, pivot + 1, high);}}static int Partition(int[] array, int low, int high){int pivotkey = array[low];while (low < high){while (low < high && array[high] >= pivotkey)high--;swap(array, low, high);while (low < high && array[low] <= pivotkey)low++;swap(array, low, high);}return low;}
1 優化選取樞軸
優化后的快速排序:
static void QuickSort(int[] array, int low, int high){int pivot;//優化小數組時的排序方案if ((high - low) > 50){//優化遞歸操作while (low < high){pivot = Partition(array, low, high);QuickSort(array, low, pivot - 1);//對低子表進行遞歸排序//QuickSort(array, pivot + 1, high);low = pivot + 1;//尾遞歸 }}//else//直接插入排序 }static int Partition(int[] array, int low, int high){//優化選取樞軸int m = low + (high - low) / 2;if (array[low] > array[high])swap(array, low, high);if (array[m] > array[high])swap(array, m, high);if (array[m] > array[low])swap(array, m, low);int pivotkey = array[low];int temp = pivotkey;while (low < high){while (low < high && array[high] >= pivotkey)high--;//優化不必要的交換//swap(array, low, high);array[low] = array[high];while (low < high && array[low] <= pivotkey)low++;//優化不必要的交換//swap(array, low, high);array[high] = array[low];}array[low] = temp;return low;}快速時間復雜度O(nlogn)
net SDK版本
void QuickSort(int[] map, int left, int right) {do {int i = left;int j = right;int x = map[i + ((j - i) >> 1)];do {while (i < map.Length && CompareKeys(x, map[i]) > 0) i++;while (j >= 0 && CompareKeys(x, map[j]) < 0) j--;if (i > j) break;if (i < j) {int temp = map[i];map[i] = map[j];map[j] = temp;}i++;j--;} while (i <= j);if (j - left <= right - i) {if (left < j) QuickSort(map, left, j);left = i;}else {if (i < right) QuickSort(map, i, right);right = j;}} while (left < right);}不穩定
轉載于:https://www.cnblogs.com/smileberry/archive/2013/02/01/2889579.html
總結
- 上一篇: jquery创建并行对象或者叫合并对象
- 下一篇: 【Demo 0011】多媒体播放器