中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

商標(biāo) 做網(wǎng)站 是幾類谷歌seo優(yōu)化

商標(biāo) 做網(wǎng)站 是幾類,谷歌seo優(yōu)化,織夢dede門戶資訊新聞網(wǎng)站源碼,網(wǎng)站銷售流程本章我們來學(xué)習(xí)一下數(shù)據(jù)結(jié)構(gòu)的排序算法! 目錄 1.排序的概念及其運(yùn)用 1.1排序的概念 1.2 常見的排序算法 2.常見排序算法的實(shí)現(xiàn) 2.1 插入排序 2.1.1基本思想: 2.1.2直接插入排序: 2.1.3 希爾排序( 縮小增量排序 ) 2.2 選擇排序 2.2…

本章我們來學(xué)習(xí)一下數(shù)據(jù)結(jié)構(gòu)的排序算法!

目錄

1.排序的概念及其運(yùn)用

1.1排序的概念

1.2?常見的排序算法

2.常見排序算法的實(shí)現(xiàn)

2.1 插入排序

2.1.1基本思想:

2.1.2直接插入排序:

2.1.3 希爾排序( 縮小增量排序 )

2.2 選擇排序

2.2.1基本思想:

2.2.2 直接選擇排序:

2.2.3 堆排序

2.3 交換排序

2.3.1冒泡排序

2.3.2 快速排序

1. hoare版本

2. 挖坑法

3. 前后指針版本??編輯

2.3.2 快速排序優(yōu)化

?2.3.3?快速排序非遞歸

2.4 歸并排序

2.5 非比較排序

3.排序算法復(fù)雜度及穩(wěn)定性分析


1.排序的概念及其運(yùn)用

1.1排序的概念

(1)排序:所謂排序,就是使一串記錄,按照其中的某個(gè)或某些關(guān)鍵字的大小,遞增或遞減的排列起來的操作。

(2)穩(wěn)定性:假定在待排序的記錄序列中,存在多個(gè)具有相同的關(guān)鍵字的記錄,若經(jīng)過排序,這些記錄的相對(duì)次???序保持不變,即在原序列中,??r [ i ] = r?[ j ],且?r [ i ]?在?r [ j ]?之前,而在排序后的序列中,??r [ i ]?仍在?r [ j ]之前,則稱這種排序算法是穩(wěn)定的;否則稱為不穩(wěn)定的。

(3)內(nèi)部排序:數(shù)據(jù)元素全部放在內(nèi)存中的排序。

(4)外部排序:數(shù)據(jù)元素太多不能同時(shí)放在內(nèi)存中,根據(jù)排序過程的要求不能在內(nèi)外存之間移動(dòng)數(shù)據(jù)的排序。

1.2?常見的排序算法

2.常見排序算法的實(shí)現(xiàn)

2.1 插入排序

2.1.1基本思想:

直接插入排序是一種簡單的插入排序法,其基本思想是:

????????把待排序的記錄按其關(guān)鍵碼值的大小逐個(gè)插入到一個(gè)已經(jīng)排好序的有序序列中,直到所有的記錄插入完為止,得到一個(gè)新的有序序列 。

實(shí)際中我們玩撲克牌時(shí),就用了插入排序的思想

2.1.2直接插入排序:

????????當(dāng)插入第i(i>=1) 個(gè)元素時(shí),前面的 array[0],array[1],…,array[i-1] 已經(jīng)排好序,此時(shí)用 array[i] 的排序碼與array[i-1],array[i-2],…的排序碼順序進(jìn)行比較,找到插入位置即將 array[i] 插入,原來位置上的元素順序后移;
代碼案例:
// 時(shí)間復(fù)雜度:O(N^2) 逆序
// 最好的情況:O(N)  順序有序
void InsertSort(int* a, int n)
{// [0, end] end+1for (int i = 0; i < n-1; ++i){int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp > a[end]){a[end + 1] = a[end];--end;}else{break;}}a[end + 1] = tmp;}
}
直接插入排序的特性總結(jié):
????????1. 元素集合越接近有序,直接插入排序算法的時(shí)間效率越高。
????????2. 時(shí)間復(fù)雜度: O(N^2)
????????3. 空間復(fù)雜度: O(1) ,它是一種穩(wěn)定的排序算法。
????????4. 穩(wěn)定性:穩(wěn)定

2.1.3 希爾排序( 縮小增量排序 )

????????希爾排序法又稱縮小增量法。希爾排序法的基本思想是:先選定一個(gè)整數(shù),把待排序文件中所有記錄分成個(gè) 組,所有距離為的記錄分在同一組內(nèi),并對(duì)每一組內(nèi)的記錄進(jìn)行排序。然后,取,重復(fù)上述分組和排序的工 作。當(dāng)?shù)竭_(dá) =1 時(shí),所有記錄在統(tǒng)一組內(nèi)排好序 。

?

?代碼案例:

// 平均O(N^1.3)
void ShellSort(int* a, int n)
{int gap = n;// gap > 1時(shí)是預(yù)排序,目的讓他接近有序// gap == 1是直接插入排序,目的是讓他有序while (gap > 1){//gap = gap / 2;gap = gap / 3 + 1;for (int i = 0; i < n - gap; ++i){int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
希爾排序的特性總結(jié):
????????1. 希爾排序是對(duì)直接插入排序的優(yōu)化。
????????2. 當(dāng) gap > 1 時(shí)都是預(yù)排序,目的是讓數(shù)組更接近于有序。當(dāng) gap == 1 時(shí),數(shù)組已經(jīng)接近有序的了,這樣就會(huì)很快。這樣整體而言,可以達(dá)到優(yōu)化的效果。我們實(shí)現(xiàn)后可以進(jìn)行性能測試的對(duì)比。
????????3. 希爾排序的時(shí)間復(fù)雜度不好計(jì)算,因?yàn)?/span> gap 的取值方法很多,導(dǎo)致很難去計(jì)算,因此在好些書中給出的希爾排序的時(shí)間復(fù)雜度都不固定:
《數(shù)據(jù)結(jié)構(gòu) (C 語言版 ) --- 嚴(yán)蔚敏

?《數(shù)據(jù)結(jié)構(gòu)-用面相對(duì)象方法與C++描述》--- 殷人昆

因?yàn)間ap是按照Knuth提出的方式取值的,而且Knuth進(jìn)行了大量的試驗(yàn)統(tǒng)計(jì),我們暫時(shí)就按照:O(n^{1.25}) 到?O(1.6*n^{1.25}) 來算。

????????4. 穩(wěn)定性:不穩(wěn)定

2.2 選擇排序

2.2.1基本思想:

????????每一次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個(gè)元素,存放在序列的起始位置,直到全部待排序的數(shù)據(jù)元素排完 。

2.2.2 直接選擇排序:

????????在元素集合array[i]--array[n-1] 中選擇關(guān)鍵碼最大 ( ) 的數(shù)據(jù)元素若它不是這組元素中的最后一個(gè)( 第一個(gè) ) 元素,則將它與這組元素中的最后一個(gè)(第一個(gè))元素交換在剩余的array[i]--array[n-2] array[i+1]--array[n-1] )集合中,重復(fù)上述步驟,直到集合剩余 1 個(gè)元素。

??代碼案例:

// 時(shí)間復(fù)雜度:O(N^2)
// 最好的情況下:O(N^2)
void SelectSort(int* a, int n)
{int begin = 0, end = n - 1;while (begin < end){int mini = begin, maxi = begin;for (int i = begin + 1; i <= end; ++i){if (a[i] < a[mini]){mini = i;}if (a[i] > a[maxi]){maxi = i;}}Swap(&a[begin], &a[mini]);if (maxi == begin){maxi = mini;}Swap(&a[end], &a[maxi]);++begin;--end;}
}
直接選擇排序的特性總結(jié):
????????1. 直接選擇排序思考非常好理解,但是效率不是很好。實(shí)際中很少使用。
????????2. 時(shí)間復(fù)雜度: O(N^2)
????????3. 空間復(fù)雜度: O(1)
????????4. 穩(wěn)定性:不穩(wěn)定

2.2.3 堆排序

????????堆排序(Heapsort) 是指利用堆積樹(堆)這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法,它是選擇排序的一種。它是通過堆來進(jìn)行選擇數(shù)據(jù)。需要注意的是排升序要建大堆,排降序建小堆。

?

?代碼案例:

void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){// 假設(shè)左孩子小,如果解設(shè)錯(cuò)了,更新一下if (child + 1 < size && a[child + 1] > a[child]){++child;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}// 升序
void HeapSort(int* a, int n)
{// O(N)// 建大堆for (int i = (n - 1 - 1) / 2; i >= 0; --i){AdjustDown(a, n, i);}// O(N*logN)int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}
}
堆排序的特性總結(jié):
????????1. 堆排序使用堆來選數(shù),效率就高了很多。
????????2. 時(shí)間復(fù)雜度: O(N*logN)
????????3. 空間復(fù)雜度: O(1)
????????4. 穩(wěn)定性:不穩(wěn)定

2.3 交換排序

????????基本思想:所謂交換,就是根據(jù)序列中兩個(gè)記錄鍵值的比較結(jié)果來對(duì)換這兩個(gè)記錄在序列中的位置,交換排序的特點(diǎn)是:將鍵值較大的記錄向序列的尾部移動(dòng),鍵值較小的記錄向序列的前部移動(dòng)。

2.3.1冒泡排序

?代碼案例:

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}// 時(shí)間復(fù)雜度:O(N^2)
// 最好情況是多少:O(N)
void BubbleSort(int* a, int n)
{for (int j = 0; j < n; j++){bool exchange = false;for (int i = 1; i < n-j; i++){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = true;}}if (exchange == false)break;}
冒泡排序的特性總結(jié):
????????1. 冒泡排序是一種非常容易理解的排序
????????2. 時(shí)間復(fù)雜度: O(N^2)
????????3. 空間復(fù)雜度: O(1)
????????4. 穩(wěn)定性:穩(wěn)定

2.3.2 快速排序

????????快速排序是Hoare 1962 年提出的一種二叉樹結(jié)構(gòu)的交換排序方法,其基本思想為: 任取待排序元素序列中 的某元素作為基準(zhǔn)值,按照該排序碼將待排序集合分割成兩子序列,左子序列中所有元素均小于基準(zhǔn)值,右 子序列中所有元素均大于基準(zhǔn)值,然后最左右子序列重復(fù)該過程,直到所有元素都排列在相應(yīng)位置上為止 。

?代碼案例:

// 假設(shè)按照升序?qū)rray數(shù)組中[left, right)區(qū)間中的元素進(jìn)行排序
void QuickSort(int array[], int left, int right)
{if(right - left <= 1)return;// 按照基準(zhǔn)值對(duì)array數(shù)組的 [left, right)區(qū)間中的元素進(jìn)行劃分int div = partion(array, left, right);// 劃分成功后以div為邊界形成了左右兩部分 [left, div) 和 [div+1, right)// 遞歸排[left, div)QuickSort(array, left, div);// 遞歸排[div+1, right)QuickSort(array, div+1, right);
}int GetMidi(int* a, int begin, int end)
{int midi = (begin + end) / 2;// begin end midi三個(gè)數(shù)選中位數(shù)if (a[begin] < a[midi]){if (a[midi] < a[end])return midi;else if (a[begin] > a[end])return begin;elsereturn end;}else{//...}
}void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;int midi = GetMidi(a, begin, end);Swap(&a[midi], &a[begin]);int left = begin, right = end;int keyi = begin;while (left < right){// 右邊找小while (left < right && a[right] >= a[keyi]){--right;}// 左邊找大while (left < right && a[left] <= a[keyi]){++left;}Swap(&a[left], &a[right]);}Swap(&a[left], &a[keyi]);keyi = left;// [begin, keyi-1] keyi [keyi+1, end]QuickSort(a, begin, keyi - 1);QuickSort(a, keyi+1, end);
}
????????上述為快速排序遞歸實(shí)現(xiàn)的主框架,發(fā)現(xiàn)與二叉樹前序遍歷規(guī)則非常像,同學(xué)們在寫遞歸框架時(shí)可想想二叉樹前序遍歷規(guī)則即可快速寫出來,后序只需分析如何按照基準(zhǔn)值來對(duì)區(qū)間中數(shù)據(jù)進(jìn)行劃分的方式即可。將區(qū)間按照基準(zhǔn)值劃分為左右兩半部分的常見方式有:
1. hoare版本

代碼案例:

int PartSort1(int* a, int begin, int end)
{int midi = GetMidi(a, begin, end);Swap(&a[midi], &a[begin]);int left = begin, right = end;int keyi = begin;while (left < right){// 右邊找小while (left < right && a[right] >= a[keyi]){--right;}// 左邊找大while (left < right && a[left] <= a[keyi]){++left;}Swap(&a[left], &a[right]);}Swap(&a[left], &a[keyi]);return left;
}void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;int keyi = PartSort1(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi+1, end);
}
2. 挖坑法

?代碼案例:

// 挖坑法
int PartSort2(int* a, int begin, int end)
{int midi = GetMidi(a, begin, end);Swap(&a[midi], &a[begin]);int key = a[begin];int hole = begin;while (begin < end){// 右邊找小,填到左邊的坑while (begin < end && a[end] >= key){--end;}a[hole] = a[end];hole = end;// 左邊找大,填到右邊的坑while (begin < end && a[begin] <= key){++begin;}a[hole] = a[begin];hole = begin;}a[hole] = key;return hole;
}void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;int keyi = PartSort2(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi+1, end);
}
3. 前后指針版本?

?代碼案例:

int PartSort3(int* a, int begin, int end)
{int midi = GetMidi(a, begin, end);Swap(&a[midi], &a[begin]);int keyi = begin;int prev = begin;int cur = prev + 1;while (cur <= end){if (a[cur] < a[keyi] && ++prev != cur)Swap(&a[prev], &a[cur]);++cur;}Swap(&a[prev], &a[keyi]);keyi = prev;return keyi;
}void QuickSort(int* a, int begin, int end)
{if (begin >= end)return;int keyi = PartSort3(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi+1, end);
}

2.3.2 快速排序優(yōu)化

1. 三數(shù)取中法選 key
2. 遞歸到小的子區(qū)間時(shí),可以考慮使用插入排序

?2.3.3?快速排序非遞歸

?代碼案例:

void QuickSortNonR(int* a, int left, int right)
{Stack st;StackInit(&st);StackPush(&st, left);StackPush(&st, right);while (StackEmpty(&st) != 0){right = StackTop(&st);StackPop(&st);left = StackTop(&st);StackPop(&st);if(right - left <= 1)continue;int div = PartSort1(a, left, right);// 以基準(zhǔn)值為分割點(diǎn),形成左右兩部分:[left, div) 和 [div+1, right)StackPush(&st, div+1);StackPush(&st, right);StackPush(&st, left);StackPush(&st, div);}StackDestroy(&s);
}
快速排序的特性總結(jié):
????????1. 快速排序整體的綜合性能和使用場景都是比較好的,所以才敢叫 快速 排序
????????2. 時(shí)間復(fù)雜度: O(N*logN)

3. 空間復(fù)雜度: O(logN)
4. 穩(wěn)定性:不穩(wěn)定

2.4 歸并排序

基本思想:
????????歸并排序(MERGE-SORT )是建立在歸并操作上的一種有效的排序算法 , 該算法是采用分治法( Divide and Conquer)的一個(gè)非常典型的應(yīng)用。將已有序的子序列合并,得到完全有序的序列;即先使每個(gè)子序列有序,再使子序列段間有序。若將兩個(gè)有序表合并成一個(gè)有序表,稱為二路歸并。 歸并排序核心步驟:

??代碼案例:

void _MergeSort(int* a, int begin, int end, int* tmp)
{if (begin >= end)return;int mid = (begin + end) / 2;// [begin, mid][mid+1, end]_MergeSort(a, begin, mid, tmp);_MergeSort(a, mid+1, end, tmp);// [begin, mid][mid+1, end]歸并int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}while(begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, 0, n - 1, tmp);free(tmp);
}//非遞歸法
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}int gap = 1;while (gap < n){printf("gap:%2d->", gap);for (size_t i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;// [begin1, end1][begin2, end2] 歸并//printf("[%2d,%2d][%2d, %2d] ", begin1, end1, begin2, end2);// 邊界的處理if (end1 >= n || begin2 >= n){break;}if (end2 >= n){end2 = n - 1;}//printf("[%2d,%2d][%2d, %2d] ", begin1, end1, begin2, end2);int j = begin1;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[j++] = a[begin1++];}else{tmp[j++] = a[begin2++];}}while (begin1 <= end1){tmp[j++] = a[begin1++];}while (begin2 <= end2){tmp[j++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) * (end2-i+1));}printf("\n");gap *= 2;}free(tmp);
}
歸并排序的特性總結(jié):
????????1. 歸并的缺點(diǎn)在于需要 O(N) 的空間復(fù)雜度,歸并排序的思考更多的是解決在磁盤中的外排序問題。
????????2. 時(shí)間復(fù)雜度: O(N*logN)
????????3. 空間復(fù)雜度: O(N)
????????4. 穩(wěn)定性:穩(wěn)定

2.5 非比較排序

思想:計(jì)數(shù)排序又稱為鴿巢原理,是對(duì)哈希直接定址法的變形應(yīng)用。 操作步驟:
????????1. 統(tǒng)計(jì)相同元素出現(xiàn)次數(shù)
????????2. 根據(jù)統(tǒng)計(jì)的結(jié)果將序列回收到原來的序列中

?代碼案例:

// 基數(shù)排序/桶排序// 計(jì)數(shù)排序
// 時(shí)間:O(N+range)
// 空間:O(range)
void CountSort(int* a, int n)
{int min = a[0], max = a[0];for (int i = 1; i < n; i++){if (a[i] < min)min = a[i];if (a[i] > max)max = a[i];}int range = max - min + 1;int* count = (int*)calloc(range, sizeof(int));if (count == NULL){printf("calloc fail\n");return;}// 統(tǒng)計(jì)次數(shù)for (int i = 0; i < n; i++){count[a[i] - min]++;}// 排序int i = 0;for (int j = 0; j < range; j++){while (count[j]--){a[i++] = j + min;}}
}
計(jì)數(shù)排序的特性總結(jié):
????????1. 計(jì)數(shù)排序在數(shù)據(jù)范圍集中時(shí),效率很高,但是適用范圍及場景有限。
????????2. 時(shí)間復(fù)雜度: O(MAX(N, 范圍 ))
????????3. 空間復(fù)雜度: O( 范圍 )

????????4. 穩(wěn)定性:穩(wěn)定

3.排序算法復(fù)雜度及穩(wěn)定性分析

?

?注:

? ? ? ? (1)算法穩(wěn)定性是指,待排序列中相同的值在排序后相對(duì)順序不變,這就是算法穩(wěn)定。

????????(2)輔助空間是指在排序的過程中開辟了新的空間。

?本篇完!

http://www.risenshineclean.com/news/65659.html

相關(guān)文章:

  • 做網(wǎng)站應(yīng)該怎么做行業(yè)數(shù)據(jù)統(tǒng)計(jì)網(wǎng)站
  • 石家莊哪有個(gè)人建站的網(wǎng)頁設(shè)計(jì)素材網(wǎng)站
  • 做童裝在哪個(gè)網(wǎng)站找客戶搜索引擎優(yōu)化seo方案
  • 推銷別人做網(wǎng)站有什么作用專業(yè)搜索引擎優(yōu)化電話
  • 南京整站優(yōu)化推廣和競價(jià)代運(yùn)營
  • 做衣服接訂單的網(wǎng)站專業(yè)搜索引擎seo技術(shù)公司
  • 做網(wǎng)站有必要要源碼嗎營銷型網(wǎng)站有哪些功能
  • 給你一個(gè)網(wǎng)站你怎么做的嗎怎么查詢最新網(wǎng)站
  • 阿里云可以建網(wǎng)站嗎網(wǎng)絡(luò)宣傳方式有哪些
  • 網(wǎng)站和網(wǎng)頁的概念免費(fèi)的網(wǎng)站域名查詢565wcc
  • 福田網(wǎng)站開發(fā)老王搜索引擎入口
  • 如何購買建設(shè)網(wǎng)站系統(tǒng)it培訓(xùn)班真的有用嗎
  • 怎樣做約票的網(wǎng)站意思電商營銷推廣方案
  • 建網(wǎng)站報(bào)價(jià) 優(yōu)幫云企業(yè)培訓(xùn)考試
  • 網(wǎng)站建設(shè)有哪些方法google seo 優(yōu)化招聘
  • 做網(wǎng)站域名服務(wù)器網(wǎng)站建設(shè)公司簡介
  • bt磁力搜索引擎win10優(yōu)化大師免費(fèi)版
  • 網(wǎng)站 微信小程序怎么做百度指數(shù)搜索
  • 北龍中網(wǎng) 可信網(wǎng)站驗(yàn)證 費(fèi)用百度手機(jī)怎么刷排名多少錢
  • 招聘網(wǎng)站分析如何做網(wǎng)店推廣方案
  • 網(wǎng)站續(xù)費(fèi)怎么做分錄百度seo關(guān)鍵詞排名優(yōu)化
  • 如何做視頻網(wǎng)站技術(shù)優(yōu)化大師軟件下載
  • 網(wǎng)站建設(shè)綿陽網(wǎng)絡(luò)營銷品牌案例
  • 專門做物理的網(wǎng)站網(wǎng)絡(luò)營銷的概念和特點(diǎn)是什么
  • 網(wǎng)站后臺(tái)登陸不進(jìn)去是怎么回事網(wǎng)絡(luò)營銷手段有哪四種
  • 網(wǎng)站上的logo怎么做有哪些網(wǎng)絡(luò)推廣平臺(tái)
  • 網(wǎng)站開發(fā)的響應(yīng)式和兼容性問題seo優(yōu)化是利用規(guī)則提高排名
  • 如何做電子書網(wǎng)站全網(wǎng)營銷系統(tǒng)是不是傳銷
  • 南京網(wǎng)站制作有限公司網(wǎng)站交易網(wǎng)
  • 做ppt找圖片在哪個(gè)網(wǎng)站重慶seo代理