溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言歸排與計排是什么

發(fā)布時間:2023-04-10 09:26:39 來源:億速云 閱讀:119 作者:iii 欄目:開發(fā)技術

這篇文章主要講解了“C語言歸排與計排是什么”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C語言歸排與計排是什么”吧!

歸并排序:是創(chuàng)建在歸并操作上的一種有效的排序算法。算法是采用分治法(Divide and Conquer)的一個非常典型的應用,且各層分治遞歸可以同時進行。歸并排序思路簡單,速度僅次于快速排序,為穩(wěn)定排序算法,一般用于對總體無序,但是各子項相對有序的數(shù)列。

1. 基本思想

歸并排序是用分治思想,分治模式在每一層遞歸上有三個步驟:

  • 分解(Divide):將n個元素分成個含n/2個元素的子序列。

  • 解決(Conquer):用合并排序法對兩個子序列遞歸的排序。

  • 合并(Combine):合并兩個已排序的子序列已得到排序結果。

歸并排序的特性總結:

1. 歸并的缺點在于需要O(N)的空間復雜度,歸并排序的思考更多的是解決在磁盤中的外排序題。
2. 時間復雜度:O(N*logN)
3. 空間復雜度:O(N)
4. 穩(wěn)定性:穩(wěn)定

C語言歸排與計排是什么

這是歸并排序的主要概念。

歸并排序有遞歸和非遞歸兩種,我們首先來實現(xiàn)遞歸的代碼

代碼

//歸并遞歸
void _MergeSore(int* arr, int left, int right, int* tmp)
{
	//遞歸結束條件
	if (left >= right)
		return;
	//int min = left + ((right - left) >> 1);
	int min = (left + right) / 2;
	//遞歸開始
	_MergeSore(arr, left, min, tmp);
	_MergeSore(arr, min + 1, right, tmp);
	//排序開始
	int begin1 = left, end1 = min;
	int begin2 = min + 1, end2 = right;
	int i = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (arr[begin1] < arr[begin2])
		{
			tmp[i++] = arr[begin1++];
			/*i++;
			begin1++;*/
		}
		if (arr[begin1] >= arr[begin2])
		{
			tmp[i++] = arr[begin2++];
			/*i++;
			begin2++;*/
		}
	}
	while (begin1 <= end1)
	{
		tmp[i++] = arr[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[i++] = arr[begin2++];
	}
	//將建立的數(shù)組拷貝到原數(shù)組中
	for (int i = 0; i <= right; i++)
	{
		arr[i] = tmp[i];
	}
}
//歸并排序
void MergeSort(int* arr, int n)
{
	//先建立一個數(shù)組,用來存放排序的元素
	int* tmp = (int*)malloc(sizeof(int) * (n));
	if (tmp == NULL)
	{
		perror("perror,file");
		return;
	}
	//歸并函數(shù)實現(xiàn)
	_MergeSore(arr, 0, n - 1, tmp);
	//銷毀新建數(shù)組,防止內(nèi)存泄漏
	free(tmp);
	//防止野指針
	tmp = NULL;
}

下面是非遞歸的寫法,非遞歸的思想與遞歸的思想幾乎一樣,大家可以自己想下過程。

  1.  申請空間,使其大小為兩個已經(jīng)排序序列之和,該空間用來存放合并后的序列

  2.  設定兩個指針,最初位置分別為兩個已經(jīng)排序序列的起始位置

  3.  比較兩個指針所指向的元素,選擇相對小的元素放入到合并空間,并移動指針到下一位置

  4.  重復步驟③直到某一指針到達序列尾

  5.  將另一序列剩下的所有元素直接復制到合并序列尾

void _MergeSoreNonR1(int* arr, int left, int right, int* tmp)
{
	int gap = 1;
	int i = 0;
	while (gap <= right)
	{
		for (i = 0; i <= right; i += 2 * gap)
		{
			//[i,I+gap-1]  [i+gap,2*gap-1]
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			//printf(" %d", end2);
			if (end1 > right)
				end1 = right;
			if (begin2 > right)
			{
				begin2 = right + 1;
				end2 = right;
			}
			if (end2 > right)
				end2 = right;
			int index = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (arr[begin1] < arr[begin2])
				{
					tmp[index++] = arr[begin1++];
				}
				if (arr[begin1] >= arr[begin2])
				{
					tmp[index++] = arr[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				tmp[index++] = arr[begin1++];
			}
			while (begin2 <= end2)
			{
				tmp[index++] = arr[begin2++];
			}
		}
 
		for (i = 0; i <= right; i++)
		{
			arr[i] = tmp[i];
		}
		gap *= 2;
	}
}
 
void MergeSortNonR(int* arr, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc,file");
		return;
	}
	_MergeSoreNonR1(arr, 0, n-1, tmp);
	free(tmp);
	tmp = NULL;
}

下面來看計數(shù)排序

計數(shù)排序不用比較兩個數(shù)的大小,它的做法是統(tǒng)計哪個元素出現(xiàn)的次數(shù),然后通過這個元素出現(xiàn)的次數(shù)來排序。

計數(shù)算法只能使用在已知序列中的元素在0-k之間,且要求排序的復雜度在線性效率上。 &Acirc; 計數(shù)排序和基數(shù)排序很類似,都是非比較型排序算法。但是,它們的核心思想是不同的,基數(shù)排序主要是按照進制位對整數(shù)進行依次排序,而計數(shù)排序主要側重于對有限范圍內(nèi)對象的統(tǒng)計?;鶖?shù)排序可以采用計數(shù)排序來實現(xiàn)。

計數(shù)排序的特性總結:
1. 計數(shù)排序在數(shù)據(jù)范圍集中時,效率很高,但是適用范圍及場景有限。
2. 時間復雜度:O(MAX(N,范圍))
3. 空間復雜度:O(范圍)
4. 穩(wěn)定性:穩(wěn)定

C語言歸排與計排是什么

代碼實現(xiàn)

void CountSort(int* arr, int n)
{
	//確定數(shù)組開辟的大小
	int max = arr[0], min = arr[0];
	for (int i = 1; i < n; i++)
	{
		if (arr[i] > max)
			max = arr[i];
		if (arr[i] < min)
			min = arr[i];
	}
	int range = max - min + 1;
	//建立一個數(shù)組
	int* count = (int*)malloc(sizeof(int) * range);
	if (count == NULL)
	{
		perror("malloc file");
		return NULL;
	}
	memset(count, 0, sizeof(int) * range);
	for (int i = 0; i < n; i++)
	{
		count[arr[i]-min]++;
	}
	int j = 0;
	for (int i = 0; i < n; i++)
	{
		while (count[i]--)
		{
			arr[j] = i+min;
			j++;
		}
	}
	free(count);
	count = NULL;
}

 下面是一張八大排序的比較圖

C語言歸排與計排是什么

感謝各位的閱讀,以上就是“C語言歸排與計排是什么”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對C語言歸排與計排是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI