国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序)

這篇具有很好參考價值的文章主要介紹了十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、冒泡排序:

二、插入排序:

三、選擇排序:

四、希爾排序:

五、堆排序:

六、快速排序:

6.1挖坑法:

6.2左右指針法

6.3前后指針法:

七、歸并排序:

八、桶排序:

九、計(jì)數(shù)排序:

9.1絕對映射:

9.2現(xiàn)對映射:

十、基數(shù)排序:?


一、冒泡排序:

1、思路:通過對待排序序列從前向后(從下標(biāo)較小的元素開始),依次對相鄰兩個元素的值進(jìn)行兩兩比較,若發(fā)現(xiàn)前一個數(shù)大于后一個數(shù)則交換,使值較大的元素逐漸從前移向后部,就如果水底下的氣泡一樣逐漸向上冒。

2、先以一個數(shù)組講解一下,然后再寫代碼:
? ? ? 待排序數(shù)組:3,9,-1,10,20
? ? ? ?第一輪排序:
? ? ? ? (1)3,9,-1,10,20 ? ? ?----3跟9比較,不交換

? ? ? ? (2)3,-1,9,10,20 ? ? ?----9比 -1大,所以9跟 -1交換

? ? ? ? (3)3,-1,9,10,20 ? ? ?----9跟10比較,不交換

? ? ? ? (4)3,-1,9,10,20 ? ? ?----10跟20比較,不交換

? ? ? ? ? ?第一輪過后,將20這個最大的元素固定到了最后的位置。

? ? ? ? ? ?在第二輪的時候20不參與冒泡。

? ? ? ?第二輪排序:
? ? ? ? ? ? 因?yàn)?0的位置已經(jīng)固定,所以只對前4個進(jìn)行排序即可:

? ? ? ? (1)-1,3,9,10,20 ? ? ?----3比 -1大,進(jìn)行交換

? ? ? ? (2)-1,3,9,10,20 ? ? ?----3跟9比較,不交換

? ? ? ? (3)-1,3,9,10,20 ? ? ?----9跟10比較,不交換

? ? ? ? ? ? 第二輪過后,將第二大的元素固定到了倒數(shù)第二個位置

? ? ? ?第三輪排序:
? ? ? ? ? ? 10和20的位置已經(jīng)確定,只需對前三個進(jìn)行排序

? ? ? ? (1)-1,3,9,10,20 ? ? ?----3和-1比較,不交換

? ? ? ? (2)-1,3,9,10,20 ? ? ?----3和9比較,不交換

? ? ? ? ? ? 第三輪過后,將第三大的元素位置確定

? ? ? ?第四輪排序:
? ? ? ? ? ? 只對前兩個元素進(jìn)行排序

? ? ? ? (1)-1,3,9,10,20 ? ? ?----3和-1比較,不交換

? ? ? ?第四輪過后,將第四大的元素位置確定,此時總共5個元素,已經(jīng)排序好4個,從而最后一個自然而然就是排好序的了

小結(jié):
設(shè)總的元素個數(shù)為n,那么由上邊的排序過程可以看出:

(1)總計(jì)需要進(jìn)行(n-1)輪排序,也就是(n-1)次大循環(huán)

(2)每輪排序比較的次數(shù)逐輪減少

(3)如果發(fā)現(xiàn)在某趟排序中,沒有發(fā)生一次交換, 可以提前結(jié)束冒泡排序

(4)時間復(fù)雜度是O(N^2) ? ? ?在有序的時候,很快,因?yàn)橛衑xchange變量優(yōu)化了代碼

? ? ? ? ?在亂序的時候很慢很慢。

#include<stdio.h>
void swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
//冒泡排序
void BubbleSort(int* a, int n)
{
	int end = n - 1;//不能是n,不然會越界
	while(end)
	{
		int exchange = 0;//優(yōu)化,比較之后沒有交換,說明已經(jīng)排好了,就break循環(huán)
		for (int i = 0; i < end; i++)
		{
			if (a[i] < a[i + 1])
			{
				swap(&a[i], &a[i + 1]);
				exchange++;
			}
		}
		if (exchange == 0) break;
		end--;
	}
}

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言


二、插入排序:

1、思路:

????????在待排序的元素中,假設(shè)前n-1個元素已有序,現(xiàn)將第n個元素插入到前面已經(jīng)排好的序列中,使得前n個元素有序。按照此法對所有元素進(jìn)行插入,直到整個序列有序。
??但我們并不能確定待排元素中究竟哪一部分是有序的,所以我們一開始只能認(rèn)為第一個元素是有序的,依次將其后面的元素插入到這個有序序列中來,直到整個序列有序?yàn)橹埂?/p>

2、舉例:

????????如下圖的插入撲克牌,當(dāng)摸到7的時候,會不自覺的與前面的數(shù)比較,如果比7大,把大的數(shù)向后挪動(swap),然后在第一個小于7的后面插入7

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言?

//插入排序
void InsertSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		if (a[i] < a[i - 1])//先判斷,如果i下標(biāo)的值大于前面的數(shù),就不進(jìn)入
		{
			int tmp = a[i];
			int j;
			for (j = i - 1; j >= 0 && a[j] >tmp; j--)
			{
				a[j+1] = a[j];
			}
			a[j+1] = tmp;
		}
	}
}
//兩次循環(huán)就可以實(shí)現(xiàn)
//內(nèi)部循環(huán)完成一趟的插入
//外層循環(huán)完成插入排序

三、選擇排序:

思路:

1.內(nèi)層循環(huán)一趟找出最小值的下標(biāo),與第一個數(shù)交換。重復(fù)找小,交換的兩個操作。
2.實(shí)際上,我們可以一趟選出兩個值,一個最大值一個最小值,然后將其放在序列開頭和末尾,這樣可以使選擇排序的效率快一倍。

但時間復(fù)雜度還是O(N^2),效率還是不高

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

//選擇排序
void SelectSort(int* a, int n)
{
	for (int i = 0; i < n-1; i++)//i<n-1當(dāng)它是最后一個數(shù)的時候不需要進(jìn)行交換排序
	{
		int min = i;
		int j;
		for (j = i; j < n; j++)
		{
			if (a[j] < a[min])
			{
				min=j;
			}
		}
		swap(&a[i], &a[min]);//交換函數(shù),前面的代碼中有出現(xiàn),我就不重復(fù)寫了
	}
}

四、希爾排序:

思路:

1.插入排序的優(yōu)化版,有一個預(yù)排序的過程。讓大的數(shù)快速的跳到后面,小的數(shù)快速的跳到前面。

2.使待排序列接近有序,然后再對該序列進(jìn)行一次插入排序。

3.相當(dāng)于把直接插入排序中的1換成gap而已。?

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

//希爾排序
/*步驟:
1.先選定一個小于N的整數(shù)gap作為第一增量,然后將所有距離為gap的元素分在同一組,并對每一組的元素進(jìn)行直接插入排序。然后再gap--,重復(fù)上述操作。
2.當(dāng)gap==1時就是直接插入排序,就相當(dāng)于整個序列被分到一組,進(jìn)行一次直接插入排序,排序完成。*/

void ShellSort(int* a, int n)
{
	//這里相當(dāng)于把插入排序的1換成gap
	int gap = n;
	while (gap>1)
	{
		gap = gap / 3 + 1;
		for (int i = gap; i < n; i++)
		{
			if (a[i] < a[i - gap])
			{
				int tmp = a[i];
				int j;
				for (j = i - gap; j >= 0 && a[j] > tmp; j-=gap)//這里是j-=gap
				{
					a[j + gap] = a[j];
				}
				a[j + gap] = tmp;
			}
		}
	}
}

五、堆排序:

先來認(rèn)識堆:

? ?1.什么是堆?

? ? ? ? ? 大堆:父親大于兒子? ? ? ? ? 小堆:父親小于兒子(父親,兒子是二叉樹的概念)

? ?2.堆的物理結(jié)構(gòu)和邏輯結(jié)構(gòu)?

? ? ? ? ? 物理結(jié)構(gòu):數(shù)組? ? ? ? ?邏輯結(jié)構(gòu):完全二叉樹

堆排序包括建堆(向下調(diào)整+循環(huán))? 堆排序(交換+向下調(diào)整)

? 1.建堆:

????????要建大堆,堆頂?shù)脑睾妥詈笠粋€數(shù)交換,然后把size--,就不會破壞堆的結(jié)構(gòu)

? 2.向下調(diào)整算法:

????????比較兩個孩子的大小,選出大的孩子,與父親比較,如果孩子大于父親,交換。然后把parent=child,child=parent*2+1;向下調(diào)整算法一共會調(diào)整h-1次

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

//向下調(diào)整算法(要滿足它下面的都滿足堆,才能用)
void AdjustDown(int* a, int n, int root)
{
	int parent = root;
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child] < a[child + 1]) child+=1;//把他移到右孩子那里
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else break;
	}
}

堆排序
void HeapSort(int* arr, int n)
{
	//建大堆
    //從最后一個根開始,就相當(dāng)于它下面的都滿足堆,就可以用向下調(diào)整算法
	for (int i = (n-1-1)/2; i >= 0; i--)//n-1-1是因?yàn)閿?shù)組的最后一個元素下標(biāo)是n-1
	{
		AdjustDown(arr, n, i);
	}
	//排序
	for (int i = n; i > 1; i--)
	{
		swap(&arr[0],&arr[i - 1]);
		AdjustDown(arr, i-1, 0);
	}
}

六、快速排序:

三種快排方法:(一定要自己嘗試著去寫,會有一些坑,自己寫才可以體會)

1.挖坑法

2.左右指針法

3.前后指針法


6.1挖坑法:

1.思想:

????????記第一個數(shù)為key,要調(diào)整key的位置,使得左邊的都要比key的小,右邊的數(shù)都比key的大。

2.步驟:

????????選出一個數(shù)據(jù)(一般是最左邊或是最右邊的)存放在key變量中,在該數(shù)據(jù)位置形成一個坑
????????還是定義一個left和一個right,left從左向右走(當(dāng)遇到大于key的值時停下來)。right從右向左走(當(dāng)遇到小于key的值時停下來)。(若在最左邊挖坑,則需要right先走;若在最右邊挖坑,則需要left先走)?

? ? ? ? 把right的那個小的數(shù)放在坑中,在把left那個位置的值放在right那個位置中

? ? ? ? 重復(fù)操作,直到left>right時結(jié)束,完成一趟,把key放在了正確的位置

? ? ? ? 最后用分治思想,分成左邊和右邊,遞歸。

?十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

//1.挖坑法的快速排序
void QuickSort(int* a,int left,int right)
{
	if (left >= right)//不能寫成pivot==left,pivot-1與left不匹配,會報(bào)錯
	{
		return;
	}
	int begin = left,end = right;
	int key = a[begin];//挖了一個關(guān)鍵字
	int pivot = begin;//挖了一個坑
	while (begin < end)
	{
		//右邊找小,一定要先右邊找小,放在pivot
		while (begin < end&&a[end] >= key)//在這里也要判斷begin < end,因?yàn)檫@里面end--
		{
			end--;
		}
		//小的放在左邊的坑里,然后形成新的坑位
		a[pivot] = a[end];
		pivot = end;
		//左邊找大
		while (begin < end && a[begin] <= key)
		{
			begin++;
		}
		a[pivot] = a[begin];
		pivot = begin;	
	}
	//begin==end	
	a[pivot] = key;

	//[left,right]
	//[left,pivot-1]  pivot  [pivot+1,right]
	//如果左子區(qū)間和右子區(qū)間都有序,就全部有序。那就分治遞歸。
	QuickSort(a, left, pivot - 1);
	QuickSort(a, pivot+1, right);
}

6.2左右指針法

思路:
1、選出一個key,一般是最左邊或是最右邊的。
2、定義一個begin和一個end,begin從左向右走,end從右向左走。(需要注意的是:若選擇最左邊的數(shù)據(jù)作為key,則需要end先走;若選擇最右邊的數(shù)據(jù)作為key,則需要bengin先走)(考慮到最后的時候相遇點(diǎn)的和key交換)。
3、在走的過程中,若end遇到小于key的數(shù),則停下,begin開始走,直到begin遇到一個大于key的數(shù)時,將begin和right的內(nèi)容交換,end再次開始走,如此進(jìn)行下去,直到begin和end最終相遇,此時將相遇點(diǎn)的內(nèi)容與key交換即可。(選取最左邊的值作為key)
4.此時key的左邊都是小于key的數(shù),key的右邊都是大于key的數(shù)
5.將key的左序列和右序列再次進(jìn)行這種單趟排序,如此反復(fù)操作下去,直到左右序列只有一個數(shù)據(jù),或是左右序列不存在時

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

void QuickSort(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int begin = left, end = right;
	int key = begin;//這里與挖坑法不同的地方,因?yàn)橐粨Qkey的那個數(shù)組中那個位置的數(shù),而不是值
	while (begin < end)
	{
		while (begin < end && a[end] >= a[key])
		{
			end--;
		}
		while (begin < end && a[begin] <= a[key])
		{
			begin++;
		}
		Swap(&a[begin], &a[end]);
	}
	Swap(&a[begin], &a[key]);
	QuickSort(a, left, begin - 1);
	QuickSort(a, begin + 1, right);
}

6.3前后指針法:

思路:
1、選出一個key,一般是最左邊。
2、起始時,prev指針指向序列開頭,cur指針指向prev+1。
3、讓cur一直向前走,當(dāng)遇到小于a[key]時,讓prev向前走一格(這個值一定大于a[key],因?yàn)槭莄ur走過的),然后a[cur]和a[prev]交換。

經(jīng)過一次單趟排序,最終也能使得key左邊的數(shù)據(jù)全部都小于key,key右邊的數(shù)據(jù)全部都大于key。

然后也還是將key的左序列和右序列再次進(jìn)行這種單趟排序,如此反復(fù)操作下去

用if(left>right)

{
? ? ? ? reurn;

}//跳出遞歸

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

void QuickSort(int* a, int left,int right)
{
	if (left >= right)
	{
		return;
	}
	int index=GetMidIndex(a,left, right);
	swap(&a[left], &a[index]);
	int key = left;
	int prev = left;
	int cur = left+1;
	while (cur <= right)
	{
		if (a[cur] < a[key])
		{
			prev++;
			swap(&a[cur], &a[prev]);
		}
		/*可以簡寫成cur++,   
		但是當(dāng)時一定要注意不要放在if語句的前面,因?yàn)閕f語句里面有讓cur與prev交換的,cur==right跳出循環(huán),但是a[cur]超過數(shù)組的范圍,會越界范圍。
        while (cur<=right&&a[cur] >= a[key])   
		{
			cur++;
		}*/
        cur++;
	}
	swap(&a[prev], &a[key]);
	QuickSort(a, left, prev - 1);
	QuickSort(a, prev+1,right);
}

?6.4優(yōu)化快排

三數(shù)取中法:取左端、中間、右端三個數(shù),然后進(jìn)行比較,將中值數(shù)當(dāng)做key

否則有序時時間復(fù)雜度為O(N^2)

三數(shù)取中法可以套入三種方法中,這里我就寫一種

//三數(shù)取中
int GetMidIndex(int* a, int left, int right)
{
	int mid = (left + right) / 2;
	if (a[mid] >= a[left])
	{
		if (a[mid] <= a[right])
		{
			return mid;
		}
		else
		{
			if (a[right] >= a[left])
			{
				return right;
			}
			else
			{
				return left;
			}
		}
	}
	else//a[left]>a[mid]
	{
		if (a[right] >= a[left])
		{
			return left;
		}
		else
		{
			if (a[right] >= a[mid])
			{
				return right;
			}
			else
			{
				return mid;
			}
		}
	}
}

//交換
void swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

//前后指針法
void QuickSort(int* a, int left,int right)
{
	if (left >= right)
	{
		return;
	}
	int index=GetMidIndex(a,left, right);
	swap(&a[left], &a[index]);
	int key = left;
	int prev = left;
	int cur = left+1;
	while (cur <= right)
	{
		if (a[cur] < a[key])
		{
			prev++;
			swap(&a[cur], &a[prev]);
		}
		cur++;
	}
	swap(&a[prev], &a[key]);
	QuickSort(a, left, prev - 1);
	QuickSort(a, prev+1,right);
}

七、歸并排序:

思路:

1.不斷的分割數(shù)據(jù),讓數(shù)據(jù)的每一段都有序(一個數(shù)據(jù)相當(dāng)于有序)

2.當(dāng)所有子序列有序的時候,在把子序列歸并,形成更大的子序列,最終整個數(shù)組有序。

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

??。?!需要開一個_MergeSort,而不是直接在MergeSort中直接遞歸,是因?yàn)镸ergeSort中有一個malloc

歸并排序很像二叉樹中的后序思想,先遞歸,遞歸到最后的時候再合并。?。?!

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

//歸并排序
void _MergeSort(int* a, int left, int right, int* tmp)//在這個函數(shù)中調(diào)用遞歸{
	if (left >= right)
	{
		return;
	}
	int mid = (left + right) >> 1;
	_MergeSort(a, left, mid, tmp);
	_MergeSort(a, mid+1, right, tmp);
	//合并
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int i = left;
	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++];
	}
	for (int j = left; j <= right; j++)
	{
		a[j] = tmp[j];
	}
}
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	_MergeSort(a, 0, n - 1, tmp);
	free(tmp);
}

八、桶排序:

思路:大問題化小

桶排序 (Bucket sort)或所謂的箱排序,是一種分塊的排序算法,工作的原理是將數(shù)組分到有限數(shù)量的桶里,每個桶的大小都相等。每個桶再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續(xù)使用桶排序進(jìn)行排序)

把待排序序列(數(shù)組)中的數(shù)據(jù)根據(jù)函數(shù)映射方法分配到若干個桶中,在分別對各個桶進(jìn)行排序,最后依次按順序取出桶中的數(shù)據(jù)。
適用于數(shù)據(jù)分配均勻,數(shù)據(jù)比較大,相對集中的情況。

//桶排序
void bucket_sort(int a[],int size,int bucket_size) {
	int i,j;        //數(shù)組,數(shù)組長度,桶的大小
 
                        //定義動態(tài)的指針數(shù)組
	KeyNode **bucket_num = (KeyNode **)malloc(bucket_size * sizeof(KeyNode*));
 
	for(i = 0;i < bucket_size;i++) 
	{
		bucket_num[i] = (KeyNode*)malloc(sizeof(KeyNode));//為每個鏈表定義頭結(jié)點(diǎn) 
		bucket_num[i]->num = 0;   
		bucket_num[i]->next = NULL;   //指針變量初始化為空
	}
 
	for(j = 0;j < size;j++) //準(zhǔn)備插入
	{
		KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));//定義一個節(jié)點(diǎn) 
		node->num = a[j];    //數(shù)據(jù)域存數(shù)據(jù) 
		node->next = NULL;	//指向空
		
		int index = a[j]/100;  //映射函數(shù) 計(jì)算桶號
		
		KeyNode *p = bucket_num[index];//p指向鏈表的頭
       
        //鏈表結(jié)構(gòu)的插入排序
		while(p->next != NULL && p->next->num <= node->num)
		{
			p = p->next;	//1.鏈表為空,p->next==NULL,進(jìn)入不了循環(huán) 
		}					//2.鏈表不為空,因?yàn)殒湵韽臒o開始按順序插入,數(shù)據(jù)為有序的,
							//可以找到    前一個節(jié)點(diǎn) <= node <=后一個節(jié)點(diǎn)
		
		//節(jié)點(diǎn)插入鏈表 
		node->next = p->next;
		p->next = node;
		(bucket_num[index]->num)++;	//記錄一下該鏈表中有幾個有效節(jié)點(diǎn) 
 
	}
	//打印結(jié)果
	KeyNode * k = NULL;  //定義一個空的結(jié)構(gòu)體指針用于儲存輸出結(jié)果
	for(i = 0;i < bucket_size;i++)
    {
        //for(k = bucket_num[i]->next;k!=NULL;k=k->next)//通過最后一個指針指向空
        k = bucket_num[i]->next;
        for(int m=0;m<bucket_num[i]->num;m++)   //通過頭指針記錄節(jié)點(diǎn)數(shù)
        {
            printf("%d ",k->num);
            k=k->next;
        			
    }		
	printf("\n");
}

九、計(jì)數(shù)排序:

一種特殊的排序,唯一種沒有比較的排序(指沒有前后比較,還是有交換的)

以數(shù)組的下標(biāo)當(dāng)做數(shù)值,有這個數(shù)的時候a[i]++;

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

?局限:適用于整數(shù)。數(shù)要求集中(否則空間的浪費(fèi)大)

9.1絕對映射:

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

int * countingSort1(int arr[],int count,int max) {
    int index = 0;
    int *tmpArr = (int *)malloc(max*sizeof(int));
    int *result = (int *)malloc(max*sizeof(int));
    
    for(int k = 0;k<max;k++) {
        tmpArr[k] = 0;
    }
    
    for (int i = 0; i<count; i++) {
        tmpArr[arr[i]]++;
    }
    for (int j = 0; j<max; j++) {
        while (tmpArr[j]) {
            result[index++] = j;
            tmpArr[j]--;
        }
    }
    free(tmpArr);
    tmpArr = NULL;
    return result;
}

9.2現(xiàn)對映射:

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言

void CountSort(int* a, int n)
{
	int max = a[0], min = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] > max) max = a[i];
		if (a[i] < min) min = a[i];
	}
	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int) * range);
	memset(count, 0, sizeof(int) * range);
	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;
		}
	}
	free(count);
}

十、基數(shù)排序:?

原理:是將整數(shù)按位數(shù)切割成不同的數(shù)字,然后按每個位數(shù)分別比較。

十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序),排序算法,算法,經(jīng)驗(yàn)分享,筆記,c語言文章來源地址http://www.zghlxwxcb.cn/news/detail-838399.html

#include<math.h>
testBS()
{
    inta[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
    int *a_p = a;
    //計(jì)算數(shù)組長度
    intsize = sizeof(a) / sizeof(int);
    //基數(shù)排序
    bucketSort3(a_p, size);
    //打印排序后結(jié)果
    inti;
    for(i = 0; i < size; i++)
    {
        printf("%d\n", a[i]);
    }
    intt;
    scanf("%d", t);
}
//基數(shù)排序
voidbucketSort3(int *p, intn)
{
    //獲取數(shù)組中的最大數(shù)
    intmaxNum = findMaxNum(p, n);
    //獲取最大數(shù)的位數(shù),次數(shù)也是再分配的次數(shù)。
    intloopTimes = getLoopTimes(maxNum);
    inti;
    //對每一位進(jìn)行桶分配
    for(i = 1; i <= loopTimes; i++)
    {
        sort2(p, n, i);
    }
}
//獲取數(shù)字的位數(shù)
intgetLoopTimes(intnum)
{
    intcount = 1;
    inttemp = num / 10;
    while(temp != 0)
    {
        count++;
        temp = temp / 10;
    }
    returncount;
}
//查詢數(shù)組中的最大數(shù)
intfindMaxNum(int *p, intn)
{
    inti;
    intmax = 0;
    for(i = 0; i < n; i++)
    {
        if(*(p + i) > max)
        {
            max = *(p + i);
        }
    }
    returnmax;
}
//將數(shù)字分配到各自的桶中,然后按照桶的順序輸出排序結(jié)果
voidsort2(int *p, intn, intloop)
{
    //建立一組桶此處的20是預(yù)設(shè)的根據(jù)實(shí)際數(shù)情況修改
    intbuckets[10][20] = {};
    //求桶的index的除數(shù)
    //如798個位桶index=(798/1)%10=8
    //十位桶index=(798/10)%10=9
    //百位桶index=(798/100)%10=7
    //tempNum為上式中的1、10、100
    inttempNum = (int)pow(10, loop - 1);
    inti, j;
    for(i = 0; i < n; i++)
    {
        introw_index = (*(p + i) / tempNum) % 10;
        for(j = 0; j < 20; j++)
        {
            if(buckets[row_index][j] == NULL)
            {
                buckets[row_index][j] = *(p + i);
                break;
            }
        }
    }
    //將桶中的數(shù),倒回到原有數(shù)組中
    intk = 0;
    for(i = 0; i < 10; i++)
    {
        for(j = 0; j < 20; j++)
        {
            if(buckets[i][j] != NULL)
            {
                *(p + k) = buckets[i][j];
                buckets[i][j] = NULL;
                k++;
            }
        }
    }
}

到了這里,關(guān)于十大排序算法(冒泡排序、插入排序、選擇排序、希爾排序、堆排序、快排、歸并排序、桶排序、計(jì)數(shù)排序、基數(shù)排序)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包