最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言超詳細講解排序算法下篇

 更新時間:2022年04月06日 08:36:05   作者:程序猿教你打籃球  
今天我們主要難點有快速排序和歸并排序,會簡單涉及到二叉樹相關(guān)知識,相對來說比較抽象!所以如果有看不懂或者不明白的地方可以看看我之前的詳解二叉樹

上期學習完了前四個排序,這期我們來學習剩下的三個排序

1、冒泡排序

 冒泡排序是我們相對最好理解的個排序,但是有些小優(yōu)化的地方我會指出來,我們先看圖解:

void BubbleSort(int* a, int n)//升序
{
	//時間復雜度O(N^2)
	while (n > 0)
	{
		int exchange = 0;
		for (int i = 1; i < n; ++i)//防止越界訪問
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);//交換
				exchange = 1;
			}
		}
		if (exchange == 0)
		{
			break;
		}
		--n;
	}
}

代碼分析:我們每排完一趟,就可以確定最后一個位置的數(shù),再者我們定義了一個exchange來判斷在排序過程中是否發(fā)生了交換,如果沒有發(fā)生交換,證明此數(shù)組已經(jīng)有序,我們可以直接跳出循環(huán),避免不必要的循環(huán)!

冒泡排序的特性總結(jié):

1. 冒泡排序是一種非常容易理解的排序

2. 時間復雜度:O(N^2) 、空間復雜度:O(1)

3. 穩(wěn)定性:穩(wěn)定

2、快速排序 ( 三種方法 )

快速排序是Hoare于1962年提出的一種二叉樹結(jié)構(gòu)的交換排序方法。

基本思想為:任取待排序元素序列中的某元素作為基準值,按照該排序碼將待排序集合分割成兩子序列,左子序列中所有元素均小于基準值,右子序列中所有元素均大于基準值,然后最左右子序列重復該過程,直到所有元素都排列在相應位置上為止。 

第一種方法是我們最常見的挖坑法: 

 代碼實現(xiàn)如下:

void QuickSort(int* a, int left, int right)//升序
{
	if (left >= right)
	{
		return;
	}
 
	int begin = left;
	int end = right;
	int pivot = begin;
	int key = a[begin];
 
	while (begin < end)
	{
		//右邊找小
		while (begin < end && a[end] >= key) //這里如果不寫begin<end的話可能會出現(xiàn)越界訪問
		{
			--end;
		}
		//小的放到左邊的坑里,自己形成了新的坑位
		a[pivot] = a[end];
		pivot = end;
        
        //左邊找大
		while (begin < end && a[begin] <= key)
		{
			++begin;
		}
		//大的放到左邊的坑里,自己形成了新的坑位
		a[pivot] = a[begin];
		pivot = begin;
	}
 
	//當begin和end相遇,證明他們兩都到了坑的位置
	pivot = begin;//隨便給一個
	a[pivot] = key;
 
	//[left, pivot - 1] pivot [pivot+ 1, right]
	//左子區(qū)間和右子區(qū)間有序,我們就有序了,如何讓他們有序呢?分治遞歸
	QuickSort(a, left, key - 1);
	QuickSort(a, key + 1, right);
}
 
//函數(shù)傳參:QuickSort(arr, 0, sizeof(arr) / sizeof(int) - 1);

 第二種方法左右指針法:

 代碼實現(xiàn)如下:

void QuickSort(int* a, int left, int right)//升序
{
	if (left >= right)
	{
		return;
	}
 
	int begin = left;
	int end = right;
	int keyi = begin;
 
	while (begin < end)
	{
		//找小
		while (begin < end && a[end] >= a[keyi])
		{
			--end;
		}
		//找大
		while (begin < end && a[begin] <= a[keyi])
		{
			++begin;
		}
		Swap(&a[begin], &a[end]);
	}
 
	Swap(&a[begin], &a[keyi]);
	keyi = begin;
 
	//[left, keyi - 1] keyIndex [keyi + 1, right]
	//左子區(qū)間和右子區(qū)間有序,我們就有序了,如何讓他們有序呢?分治遞歸
 
	QuickSort(a, left, keyi - 1);
	QuickSort(a, keyi + 1, right);
}

 第三種方法前后指針法: 

代碼實現(xiàn)如下: 

void QuickSort(int* a, int left, int right)//升序
{
	if (left >= right)
	{
		return;
	}
 
	int keyi = left;
	int prev = left;
	int cur = left + 1;
	while (cur <= right)
	{
        //++prev != cur為了防止自己跟自己交換造成不必要的消耗
		if (a[cur] < a[keyi] && ++prev != cur)
		{
			Swap(&a[prev], &a[cur]);
		}
		++cur;
	}
	Swap(&a[keyi], &a[prev]);
	keyi = prev;
	
	//[left, keyi - 1] keyi [keyi + 1, right]
	//左子區(qū)間和右子區(qū)間有序,我們就有序了,如何讓他們有序呢?分治遞歸
 
	QuickSort(a, left, keyi - 1);
	QuickSort(a, keyi + 1, right);
}

3、歸并排序

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

歸并排序我們思想還是和快排思想差不多采用分治算法,當數(shù)組被分為單獨一個元素就是有序的了(見上圖),在接著歸并到一個數(shù)組中,即可實現(xiàn)排序!

 代碼實現(xiàn)如下:

void _MergeSort(int* a, int left, int right, int* tmp)
{
	if (left >= right)
		return;
 
	int mid = (left + right) >> 1;
	// 假設[left, mid] [mid + 1, right] 有序,那么我們就可以歸并了
	_MergeSort(a, left, mid, tmp);
	_MergeSort(a, mid + 1, right, tmp);
 
	//歸并
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
		{
			tmp[index++] = a[begin1++];
		}
		else
		{
			tmp[index++] = a[begin2++];
		}
	}
 
	while (begin1 <= end1)
	{
		tmp[index++] = a[begin1++];
	}
 
	while (begin2 <= end2)
	{
		tmp[index++] = a[begin2++];
	}
 
	//拷貝回去
	for (int i = left; i <= right; ++i)
	{
		a[i] = tmp[i];
	}
}
 
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	_MergeSort(a, 0, n - 1, tmp);
 
	free(tmp);
}

4、排序算法復雜度及穩(wěn)定性分析 

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

gitee(碼云):Mercury. (zzwlwp) - Gitee.com

到此這篇關(guān)于C語言超詳細講解排序算法下篇的文章就介紹到這了,更多相關(guān)C語言 排序算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c語言使用fdk_aac實現(xiàn)aac音頻解碼為pcm

    c語言使用fdk_aac實現(xiàn)aac音頻解碼為pcm

    這篇文章主要為大家詳細介紹了c語言如何使用fdk_aac庫實現(xiàn)aac音頻解碼為pcm的功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-11-11
  • 詳解C++異常處理機制示例介紹

    詳解C++異常處理機制示例介紹

    任何東西都可以認為是異常,錯誤只是異常的一種。本文將帶大家了解C++中異常是什么,是如何捕獲和處理的等相關(guān)知識。文中示例代碼簡潔易懂,感興趣的小伙伴可以了解一下
    2022-08-08
  • C++對cin輸入字符的判斷及分段函數(shù)處理方法示例

    C++對cin輸入字符的判斷及分段函數(shù)處理方法示例

    這篇文章主要介紹了C++對cin輸入字符的判斷及分段函數(shù)處理方法,結(jié)合實例形式分析了C++輸入判斷及處理相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • C++ CopyFile,MoveFile用法案例詳解

    C++ CopyFile,MoveFile用法案例詳解

    這篇文章主要介紹了C++ CopyFile,MoveFile用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 淺談QT打包的兩種方式

    淺談QT打包的兩種方式

    本文主要介紹了淺談QT打包的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • C語言實現(xiàn)獲取文件MD5值

    C語言實現(xiàn)獲取文件MD5值

    MD5(Message?Digest?Algorithm?5)是一種常用的哈希函數(shù)算法,這篇文章主要介紹了C語言如何獲取文件MD5值,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-08-08
  • C++實現(xiàn)教工考勤信息管理系統(tǒng)

    C++實現(xiàn)教工考勤信息管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)教工考勤信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++類模板以及保存數(shù)據(jù)到文件方式

    C++類模板以及保存數(shù)據(jù)到文件方式

    這篇文章主要介紹了C++類模板以及保存數(shù)據(jù)到文件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換

    C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換

    這篇文章主要介紹了C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換的相關(guān)資料,希望通過本文能幫助到大家,讓大家學習理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • Linux?C/C++實現(xiàn)顯示NIC流量統(tǒng)計信息

    Linux?C/C++實現(xiàn)顯示NIC流量統(tǒng)計信息

    NIC流量統(tǒng)計信息是由操作系統(tǒng)維護的,當數(shù)據(jù)包通過NIC傳輸時,操作系統(tǒng)會更新相關(guān)的計數(shù)器,通過讀取這些計數(shù)器,我們可以獲得關(guān)于網(wǎng)絡流量的信息,下面我們就來學習一下如何通過C/C++實現(xiàn)顯示NIC流量統(tǒng)計信息吧
    2024-01-01

最新評論

北辰区| 佛坪县| 山阴县| 象州县| 东乡| 长葛市| 方正县| 罗甸县| 松桃| 河西区| 大同市| 临泉县| 正阳县| 金川县| 盐津县| 香港| 富平县| 贵溪市| 潼南县| 忻城县| 锦州市| 承德县| 同心县| 常山县| 什邡市| 漾濞| 襄樊市| 宁国市| 夏河县| 治县。| 汝城县| 嘉黎县| 咸丰县| 凤山市| 丰台区| 鸡西市| 新沂市| 莱西市| 乌恰县| 喀喇| 禹州市|