真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【C/C++】排序總結(jié)

#pragma once
#include
#include
using namespace std;

//直接排序:指的是設(shè)定2個(gè)下標(biāo)/指針。然后從下標(biāo)1開(kāi)始進(jìn)行比較,
//升序情況下:若在前的下標(biāo)/指針大于當(dāng)前比較數(shù)值。就進(jìn)行數(shù)組的后移。
//直到滿足當(dāng)前序列值。然后最終將當(dāng)前比較數(shù)值進(jìn)行替換。
//PS:總有一個(gè)指針遍歷比較數(shù)組(k,arry[i])
//時(shí)間復(fù)雜度為:0(n^2),空間復(fù)雜度0(1)
void InsertSort(int* arry,int len)
{
	assert(arry);
	for(int i = 1; i < len;++i)
	{
		int j = i-1;
		int k = arry[i];
		while(j > -1 && arry[j] > k)
		{
			arry[j + 1] = arry[j];
			--j;
		}
		arry[j+1] = k;
	}
}

//希爾排序:在直接排序的基礎(chǔ)上增加分組Gap值,
//利用Gap值,比較對(duì)應(yīng)(len/gap)* i的位置。每個(gè)位置代表一個(gè)分組
//然后將i的值依次增加到len-gap的位置相當(dāng)于我已經(jīng)比較了每個(gè)對(duì)應(yīng)分組,使當(dāng)前序列趨近于有序。
//然后我們縮小gap值的范圍,使其接近于2,證明還需要進(jìn)行分組排序。
//0(n^2),0(1);
void ShellSort(int *arry,int len)
{
	assert(arry);
	int gap = len;
	while(gap > 1)
	{
		gap = gap/3 + 1;
		for(int i = 0; i < len - gap;++i)
		{
			int j = i;
			int k = arry[i+gap];
			while(j > -1 && arry[j] > k)
			{
				arry[j + gap] = arry[j];
				j -= gap;
			}
			arry[j+gap] = k;
		}
	}
}

//選擇排序:其實(shí)這個(gè)排序的思路比較簡(jiǎn)單,我們只需要每次遍歷數(shù)組
//得到最小/最大(或者2者都選),然后將最大值最小值分別丟到數(shù)組的最左端還有最右端然后縮小范圍就可以了。
//然后值得注意的是。我們?cè)谕瑫r(shí)得出當(dāng)前最大最小值時(shí)候,需要注意
//當(dāng)前選出的最大值最小值在進(jìn)行其中一次交換后,會(huì)不會(huì)將max與min相交換。
//0(n^2),0(1)

void SelectSort(int *arry, int len)
{
	assert(arry);
	for(int i = 0, j = len-1;i < j;++i,--j)
	{
		int min = i;
		int max = j;
		for(int k = i;k <= j;++k)
		{
			if(arry[k] < arry[min])
			{
				min = k;
			}
			if(arry[k] > arry[max])
			{
				max = k;
			}

			if(min != i)
			{
				int temp = arry[min];
				arry[min] = arry[i];
				arry[i] = temp;
			
				if(max == i)
					max = min;
			}

			if(max!= j)
			{
				int temp = arry[max];
				arry[max] = arry[j];
				arry[j] = temp;
			}
		}
	}
}

//冒泡排序:冒泡排序比較簡(jiǎn)單,就不多說(shuō)了。
//需要注意的是我們可以利用一個(gè)標(biāo)記值來(lái)確定我們需不需要進(jìn)行這一次的冒泡
//如果需要進(jìn)行冒泡的話我們的標(biāo)記值就會(huì)設(shè)置位開(kāi)關(guān)。
//然后我們就可以減少我們所需要排序的次數(shù)。
//0(n^2),0(1)

void BubbleSort(int *arry,int len)
{
	assert(arry);
	for(int i = 0;i < len -1;++i)
	{
		for(int j = len - 1;j >= i;--j)
		{
			if(arry[j] < arry[j-1])
			{
				int temp = arry[j];
				arry[j] = arry[j - 1];
				arry[j - 1] = temp;
			}
		}
	}
}


//快速排序:我們快速排序的大概思路就是選擇一頭一尾的2個(gè)下標(biāo)/指針,然后我們利用指針選擇法
//將大數(shù)與小數(shù)集中排列。將我們所選的key值建為關(guān)鍵值,大于放左邊,小于放右邊。然后不斷縮小范圍就好了
//提高效率的辦法就是我們可以在當(dāng)前序列的值小于某個(gè)數(shù)值的時(shí)候我們選擇使用插入排序。
//這可以有效的提高我們排序的效率。
//一前一后只適用于數(shù)組。
//0(nlogn),0(logn)
int _QuickSort(int* arry,int left,int right)
{
	assert(arry);
	if(left >= right)
		return  0;
	int tmp = arry[right];
	int index = right;
	--right;
	while(left = tmp)
			++right;
		if(left < right)
		{
			swap(arry[left],arry[right]);
		}
	}
	if(tmp <= arry[right])
	{
		swap(arry[right],arry[index]);
	}
	return right;
}

void QuickSort(int *arry,int left,int right)
{
	assert(arry);
	if(left < right)
	{
		int mid = _QuickSort(arry,left,right);
		QuickSort(arry,mid+1,right);
		QuickSort(arry,left,mid-1);

	}
}


//快速排序:前后指針,我們選擇一個(gè)緊緊跟隨的2個(gè)指針,原理跟一前一后相同,知識(shí)進(jìn)行了大數(shù)小數(shù)的堆置、
//這樣的方法可以利用到指針中,當(dāng)然了,key值得選擇很重要,
//最壞的情況就是選擇到了有序數(shù)組的最大數(shù)/最小數(shù),就會(huì)出現(xiàn)最壞的情況。
//選擇3數(shù)取中法可以有效地避免這個(gè)情況的出現(xiàn)。


void swap(int* arry,int left,int right)
{
	int tmp;
	tmp = arry[left];
	arry[left] = arry[right];
	arry[right] = tmp;
}

void QuickSort_On(int* arry,int left,int right)
{
	int i,last;
	if(left >= right)
		return ;
	swap(arry,left,(left+(right-left)/2));
	last = left;
	for(i = left +1;i <= right;++i)
	{
		if(arry[i] < arry[left])
			swap(arry,++last,i);
	}
	swap(arry,left,last);
	QuickSort_On(arry,left,last - 1)  ;         
	QuickSort_On(arry,last +1,right);

}



//歸并排序:利用樹(shù)的分支然后在利用區(qū)間的整合,實(shí)現(xiàn)排序完成。
//每次我們確定一個(gè)區(qū)間(n/2),然后不斷進(jìn)行2分的拆分。
//在沒(méi)2個(gè)區(qū)間中我們進(jìn)行比較排序,對(duì)每個(gè)區(qū)間的首部進(jìn)行比較,然后規(guī)整到我們需要保存的數(shù)組中。
//最后我們通過(guò)不斷的拆分,不斷地歸并復(fù)制,就可以出現(xiàn)相對(duì)的排序序列了。
//0(nlogn),0(n)
void Merge(int* arry,int* dest,int begin1,int end1,int begin2, int end2)
{
	int index = begin1;
	while(begin1 <= end1 && begin2 <= end2)
	{
		if(arry[begin1] < arry[begin2])
		{
			dest[index++] = arry[begin1++];
		}
		else
		{
			dest[index++] = arry[begin2++];
		}
	}

	if(begin1 <= end1)
	{
		while(begin1 <= end1)
		{
			dest[index++] = arry[begin1++];
		}
	}

	else
	{
		while(begin2 <= end2)
			dest[index++] = arry[begin2++];
	}
}

void _Merge(int* arry,int* dest, int left,int right)
{
	//因?yàn)槭亲箝]右開(kāi)。
	int mid = left+((right - left) /2);
	if(left < right -1)
	{
		
		//int mid = left+((right - left)>>1);
		_Merge(arry,dest,left,mid);
		_Merge(arry,dest,mid+1,right);

		Merge(arry,dest,left,mid,mid+1,right);

		//memcpy(arry+left,dest+left,sizeof(int)* (right - left +1));
	}
	Merge(arry,dest,left,mid,mid+1,right);
	memcpy(arry+left,dest+left,sizeof(int)* (right - left +1));
}

void MergeSort(int *arry,size_t size)
{
	int* dest = new int[size];
	_Merge(arry,dest,0,size-1);
	//memcpy(arry,dest,sizeof(int)* (11));
	delete[] dest;
}

總結(jié):

創(chuàng)新互聯(lián)公司是一家專注于做網(wǎng)站、網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),和平網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:和平等地區(qū)。和平做網(wǎng)站價(jià)格咨詢:18982081108

  其中時(shí)間復(fù)雜度為nlogn的有快速排序,歸并排序,堆排序。其中快速排序最壞的情況是n^2,其余都是n^2,希爾排序介于n-n^2之間。

  對(duì)于穩(wěn)定性來(lái)說(shuō),冒泡排序,插入排序,歸并排序是穩(wěn)定的,其他的排序在不同的情況下穩(wěn)定性會(huì)不同。

  對(duì)于空間復(fù)雜度來(lái)說(shuō),快速排序的空間復(fù)雜度是0(logn),歸并排序是0(n)

下面是只能在限定條件里面使用的基數(shù)排序和計(jì)數(shù)排序:

計(jì)數(shù)排序:時(shí)間復(fù)雜度:O(N), 空間復(fù)雜度O(最大數(shù)-最小數(shù))

基數(shù)排序:時(shí)間復(fù)雜度:O(N*位數(shù)),空間輔助度O(N)

//基數(shù)排序:利用哈希桶原理把數(shù)據(jù)排序,可選擇從低位到高位或從高位到低位
//利用稀疏矩陣壓縮存儲(chǔ)進(jìn)行數(shù)據(jù)定位
int  GetDigit(int* arr, size_t size)
{
    int maxDigit = 1;
    int maxNum = 10;
    for (int i = 0; i < size; ++i)
    {
        if (arr[i] >= maxNum)
        {
            int count = maxDigit;
            while (maxNum <= arr[i])
            {
                maxNum *= 10;
                ++count;
            }
            maxDigit = count;
        }
    }
    return maxDigit;
}
void LSDSort(int* arr, size_t size)//從低位開(kāi)始排  MSD從高位開(kāi)始排
{
    int counts[10] = { 0 };//存位數(shù)對(duì)應(yīng)數(shù)據(jù)個(gè)數(shù)
    int startCounts[10] = { 0 };
    int *bucket = new int[size];
    int digit = 1;//表示先取各位
    int maxDigit = GetDigit(arr, size);
    int divider = 1;//除數(shù)
    while (digit++ <= maxDigit)
    {
        memset(counts, 0, sizeof(int) * 10);
        memset(startCounts, 0, sizeof(int) * 10);
        for (int i = 0; i < size; ++i)
            counts[(arr[i]/divider)% 10]++;
        for (int i = 1; i < 10; ++i)
            startCounts[i] = startCounts[i - 1] + counts[i - 1];
        for (int i = 0; i < size; ++i)
        {
            bucket[startCounts[(arr[i] / divider) % 10]++] = arr[i];
        }
        divider *= 10;
        memcpy(arr, bucket, sizeof(int)*size);
    }
    memcpy(arr, bucket, sizeof(int)*size);
    delete[] bucket;
}
 
//計(jì)數(shù)排序
void CountSort(int *arr, size_t size,int len)
{
    int* bitMap = new int[len];
    memset(bitMap, 0, sizeof(int)*len);
    for (int i = 0; i < size; ++i)
    {
        int index = arr[i] >>5;//除以32
        int count = arr[i] % 32;
        bitMap[index] |= (1 << count);
         
    }
    int index = 0;
     
    for (int i = 0; i < len; ++i)
    {
        int count = 0;
        while (count <32&&index

這兩個(gè)排序的使用環(huán)境只能夠在特定的條件下使用,所以沒(méi)有納入常規(guī)的排序手法中,但是可以看出他的效率十分驚人。


分享標(biāo)題:【C/C++】排序總結(jié)
文章轉(zhuǎn)載:http://weahome.cn/article/jhjeio.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部