【数据结构】八大排序算法(以升序为例)

目录

​编辑 

一、直接插入排序

基本思想

实现

特点

二、希尔排序

基本思想

实现

 特点

三、选择排序

基本思想 

实现

特点

四、堆排序

基本思想

实现

特点 

五、冒泡排序

基本思想

实现

特点 

六、快速排序

1.hoare版本

基本思想

实现

2.挖坑法

基本思想

实现

3.前后指针法

基本思想

实现

4.非递归版本

基本思想

实现

5.总结

七、归并排序

基本思想

实现

特点

八、计数排序

 基本思想 

实现

特点


一、直接插入排序

 

基本思想

1.在前n个有序元素中插入一个数x。

2.从第n个数开始依次和x进行比较,比x大的数依次向后移一个单位,遇到比x小的元素,停止比较,插入x。

3.从数组的第一个元素开始,依次执行1和2直到整个数组有序。

实现

对于一个数组长度为n的整型数组,先考虑单趟的情况。

对于[0,end]的区间,将a[end+1]插入到合适的位置,区间内的元素为升序。

1.如果a[end+1]比至少一个区间内的元素大,则将其插入位置为比它小和比它大的元素中间;

2.如果a[end+1]比区间中的所有元素都小,则其插入位置为数组的首位。

代码:

void InsertSort(int* arr, int n)
{
	int end = 0;
	for (int i = 0;i < n - 1;i++)
	{
		end = i;
		int x = arr[end + 1];//即将要插入前[0,end]区间元素的值
		while (end >= 0)
		{
            //比x大的元素都往后挪一位
			if (arr[end] > x)
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				break;
			}
		}
		arr[end + 1] = x;//插入
	}
}

特点

1.数组元素越有序,直接插入排序的效率越高。

2.时间复杂度为O(N^2)。

当数组为逆序排列时,为最坏的情况,时间复杂度的精确值为1+2+3+...+(n-1)=n(n-1)/2

3.空间复杂度O(1)

二、希尔排序

基本思想

1.希尔排序于直接插入排序的区别是引入了间隔gap,对于一个数组而言,先进行预排序,再进行直接插入排序。

2.gap不断缩小的过程也就是预排序的过程。

3.gap=1则为直接插入排序。

实现

1.间隔gap大于1时的预排序本质也是插入排序。

代码:

void ShellSort(int* arr, int n)
{
	int gap = n;
	while(gap > 1)
	{
        //当gap>1时为预排序;gap=1时为直接插入排序
        //预排序后数组已经接近有序,直接插入排序的效率高
		gap = gap / 2;
		for (int j = 0;j < n - gap;j++)
		{
			int end = j;
			int x = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > x)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = x;
		}
	}
}

 特点

1.希尔排序是直接插入排序的变式

2.时间复杂度O(N^1.3)

3.空间复杂度O(1)

三、选择排序

基本思想 

1.从数组中找到最大值或最小值;

2.将最大值或最小值与数组最右边或最左边的值进行交换。

3.对剩余数组元素(已经交换至最右边或最左边的元素不再参与)继续进行操作1和2。

实现

除了最基础的选择排序,还可进行优化,单趟排序查找数组的最大和最小元素,将其分别放到数组的最右端和最左端,然后对剩余数组做相同的操作,直到数组有序。

双指针法(双下标)。

代码:

void SelectSort(int* arr, int n)
{
	int begin = 0;
	int end = n - 1;
    //保证剩余数组部分不为空
	while (begin < end)
	{
        //设置数组最大值和最小值的初始下标为begin
		int min = begin;
		int max = begin;
        //查找数组元素的最大值和最小值,并记录下标max和min
		for (int i = begin + 1;i <= end;i++)
		{
			if (arr[i] < arr[min])
			{
				min = i;
			}
			if (arr[i] > arr[max])
			{
				max = i;
			}
		}
        //将数组元素的最小值和数组首元素交换
		Swap(&arr[min], &arr[begin]);
        //由于数组首元素已经置换成最小元素,如果本来是数组最大元素,则需进行特殊处理,将最 
          大元素的下标置为最小元素的原下标
		if (begin == max)
		{
			max = min;
		}
        //将数组元素的最大值和数组最后一个元素交换
		Swap(&arr[max], &arr[end]);
        //交换后原数组的最大元和最小元素不参与后续的排序
		begin++;
		end--;
	}
}

特点

1.选择排序的工作量与数组长度直接挂钩,与数组的有序程度无关。

2.时间复杂度O(N^2)。

3.空间复杂度O(1),没有开辟额外的空间。

四、堆排序

基本思想

1.排升序,建大堆;排降序,建小堆。

(建大堆后,交换堆顶和最后一个元素,交换后不考虑最后一个元素,因为堆是用数组进行存储的,堆顶元素即数组的第一个元素,最后一个元素即数组的最后一个元素,所以排升序是建大堆,反之亦然。)

2.建堆结束后,开始进行排序的中心步骤——堆顶元素和最后一个元素进行交换,交换后的最后一个元素排除在外,堆顶元素进行向下调整。

3.继续执行步骤2,直到所有元素都被排除在外。

实现

1.建大堆可通过从最右下角的子树开始,从右向左,总下到上执行向下调整算法。

2.整个算法都是在原数组上进行操作,无需开辟额外空间。

代码:

//向下调整 建大堆
void AdjustDown(int* arr, int n, int parent)
{
	assert(arr);
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n)
		{
			child = arr[child] > arr[child + 1] ? child : child + 1;
		}
		if (arr[parent] < arr[child])
		{
			Swap(&arr[parent], &arr[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//堆排序
void HeapSort(int* arr, int n)
{
	//建大堆
	for (int i = (n - 1 - 1) / 2;i >= 0;i--)
	{
		AdjustDown(arr, n, i);
	}

	//交换堆顶和堆中最后一个元素
	//将end-1
	//向下调整
	int end = n - 1;
	while (end > 0)
	{
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, end, 0);
		end--;
	}
}

特点 

1.数组元素的有序性对堆排序几乎没什么影响,建大堆本身会使数组变得无序。

2.时间复杂度O(NlogN)

3.空间复杂度O(1),没有开辟额外的空间。

五、冒泡排序

基本思想

1.从数组首元素开始,依次和右边的元素进行大小比较,如果比右边的元素大就进行值交换。

2.单趟排序至少能让最大的元素归位,最大的元素归位后不再参与后续的排序。

3.重复执行步骤1,最糟糕的情况需要有n-1趟排序。

4.设置变量来标志当趟排序是否有值交换,若没有则说明当趟排序时数组已经有序,无需再继续排序。

实现

1.利用循环实现多趟排序,设置flag来标志数组是否有序。

代码:

void BubbleSort(int* arr, int n)
{
	for (int i = 0;i < n;i++)
	{
		int flag = 0;//假设数组已经有序
		for (int j = 0;j < n - i - 1;j++)
		{
            //比较元素和右边相邻元素的大小,比右边元素大则进行值交换
			if (arr[j] > arr[j + 1])
			{
				Swap(&arr[j], &arr[j + 1]);
				flag = 1;
			}
		}
		//已经有序了,无需继续进行排序
		if (flag == 0)
			break;
	}
}

特点 

1.由于设置了标志变量,数组越接近有序,排序的次数会越少。

2.但当数组元素较大时优化效果微乎其微。

3.时间复杂度:O(N^2)

4.空间复杂度O(1),没有开辟额外的空间。

六、快速排序

1.hoare版本

基本思想

1.将数组最左边元素的值赋值给key。

2.设置左右指针L和R,L和R错开移动,最左边元素作key,则R先动,以保证L和R相遇时所指的元素值小于key。

3.R指向的元素大于key时R向左移动,遇到小于key的元素时停止,然后L移动,遇到大于key的元素时停止,交换L和R所指元素。

4.再次执行步骤3,直到L和R相遇。

5.相遇后,交换相遇处的元素和最左边的元素。

6.递归实现整个数组的排序。

实现

1.用双指针,错开移动,相遇结束。

2.单趟排序结束后key归位,然后再分别对key左右两边的数组部分进行相同的操作,可用递归实现。

代码:

// 快速排序hoare版本
int PartSort1(int* arr, int begin, int end)
{
	if (begin >= end)
		return -1;

	int left = begin, right = end;
	int key_i = left;//左端点的值做key
	while (left < right)
	{
		//right先走,找小
		while (left < right && arr[right] >= arr[key_i])
		{
			--right;
		}
		//left再走,找大
		while (left < right && arr[left <= arr[key_i]])
		{
			++left;
		}
		Swap(&arr[left], &arr[right]);
	}
	Swap(&arr[left], &arr[key_i]);
	key_i = left;

	return key_i;
}

void QuickSort(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int key_i = PartSort1(arr, begin, end);
	//递归
	QuickSort(arr, begin, key_i - 1);
	QuickSort(arr, key_i + 1, end);

}

2.挖坑法

基本思想

1.挖坑版是hoare的“民间版“,挖坑的方法便于理解。

2.将数组首元素赋值给key,将首元素位置视为空,设置左右指针L和R,左右指针错开填坑。

3.右指针先动,遇到比key小的元素是停下来,将该较小元素填入首元素的位置,得到一个新的坑位;左指针开始移动,遇到比key大的元素停下来,将该较大元素填入新的坑位,直到L和R相遇,将key填入相遇时的坑位。

4.一轮操作后,key找准了自己的位置,而后对key左右的部分数组进行相同的操作,利用递归来实现。

实现

与hoare版本相似

代码:

// 快速排序挖坑法
int PartSort2(int* arr, int begin, int end)
{
	if (begin >= end)
		return -1;

	int left = begin, right = end;
	int key = arr[left];
	int hole = left;//坑在左端
	while (left < right)
	{
		//right先走,找小
		while (left < right && arr[right] >= key)
		{
			--right;
		}
		//填左边的坑
		arr[hole] = arr[right];
		hole = right;//坑在右端

		//left再走,找大
		while (left < right && arr[left] <= key)
		{
			++left;
		}
		//填右边的坑
		arr[hole] = arr[left];
		hole = left;
	}
	arr[hole] = key;
	return hole;
}

void QuickSort(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int key_i = PartSort2(arr, begin, end);
	//递归
	QuickSort(arr, begin, key_i - 1);
	QuickSort(arr, key_i + 1, end);

}

3.前后指针法

 

基本思想

1.数组的首元素赋值给key。

2.设置前后指针prev和cur,将指针分别初始化为第一个元素和第二个元素的下标。

3.以cur为下标的元素与key比较,比key小则prev后移一位后与cur所指元素进行交换,否则cur向前挪动,prev不动。

4.执行3操作直到cur遍历整个数组,将prev所指元素和首元素进行交换,交换后key归位。

5.对key左右两边的数组进行相同的操作,利用递归实现。

实现

代码:

// 快速排序前后指针法
int PartSort3(int* arr, int begin, int end)
{
	if (begin >= end)
		return -1;
	int prev = begin, cur = begin + 1;
	int key_i = begin;
	while (cur <= end)
	{
		//cur找比key小的值,找到后prev++,然后交换arr[prev]和arr[cur]
		if(arr[cur] < arr[key_i])
		{
			Swap(&arr[++prev], &arr[cur]);
		}
		cur++;
	}
	Swap(&arr[prev], &arr[key_i]);
	key_i = prev;
	return key_i;
}

void QuickSort(int* arr, int begin, int end)
{
	if (begin >= end)
		return;
	int key_i = PartSort3(arr, begin, end);
	//递归
	QuickSort(arr, begin, key_i - 1);
	QuickSort(arr, key_i + 1, end);

}

4.非递归版本

基本思想

1.利用数据结构——栈,存储进行排序的起始和终止下标;

2.利用获取栈顶元素和出栈的方法以及栈“先进后出”的特点将key的左右区间的起止下标存入栈(先右后左);

3.获取栈顶元素、出栈相结合,得到待排序数组的起始和终止下标,调用三种排序函数中的一个,进行排序。

4.2和3相结合,直到栈为空,排序结束。

实现

代码:

// 快速排序 非递归实现
void QuickSortNonR(int* arr, int begin, int end)
{
	Stack st;
	StackInit(&st);
	StackPush(&st, begin);
	StackPush(&st, end);

	while (!StackEmpty(&st))
	{
		int right = StackTop(&st);
		StackPop(&st);
		int left = StackTop(&st);
		StackPop(&st);

		int key_i = PartSort3(arr, left, right);
		if (right > key_i+1)
		{
			StackPush(&st, key_i + 1);
			StackPush(&st, right);
		}
		if (left < key_i-1)
		{
			StackPush(&st, left);
			StackPush(&st, key_i - 1);
		}	
	}
	StackDestroy(&st);
}

5.总结

1.快速排序效率高,但递归调用栈帧消耗大,当数组长度较大时,可用通过小区间采用插入排序,以减少递归调用次数来减少调用栈帧的消耗。

2.当被排序数组几乎接近有序时,快排处于劣势,时间复杂度为O(N^2),可采用三数取中的方法来进行优化。但是对于几乎全部相同的数组这种方法不能解决。

代码:

//三数取中
int GetMidIndex(int* arr, int begin, int end)
{
	int mid = (begin + end) / 2;
	if (arr[begin] < arr[end])
	{
		if (arr[begin] > arr[mid])
			return begin;
		else
		{
			if (arr[mid] < arr[end])
				return mid;
			else
				return end;
		}
	}
	else//arr[begin] > arr[end]
	{
		if (arr[end] > arr[mid])
			return end;
		else
		{
			if (arr[begin] > arr[mid])
				return mid;
			else
				return begin;
		}
	}
}

3.时间复杂度O(NlogN)

4.空间复杂度O(logN)    递归建立函数栈帧

七、归并排序

 

基本思想

1.归并排序的基本思想时分治思想,即分而治之。

2.将数组进行区间的划分,将一个个区间进行排序,而单个元素可以被视为一个个有序的区间,所以”分“的最底层结果是将数组拆分成一个个元素。

3.将有序的区间进行合并,再重新排序使之有序。排序的方法是在一个额外的数组空间里进行”尾插“,即将两个有序区间的较小值进行插入,直到两个区间的值都插入完毕,得到的即为两个有序区间合并后的有序区间。

4.用递归的思想或非递归的思想来实现区间的”分“和”并“。

实现

1.递归版本

与二叉树的前序遍历相似。

代码:

void _MergeSort(int* a, int begin, int end, int* tmp)
{
	//理论上不可能出现begin>end的情况,但是当begin=end时,
	//默认该区间为有序,不用进行归并,这是递归的出口
	if (begin >= end)
		return;

	int mid = (begin + end) / 2;
	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	//递归
	_MergeSort(a, begin1, end1, tmp);
	_MergeSort(a, begin2, end2, tmp);

	//归并
	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 failed!");
	}

	_MergeSort(a, 0, n - 1, tmp);
	//释放动态申请的内存
	free(tmp);
	tmp = NULL;
}

2.非递归版本

递归版本调用堆栈较多,为了减少额外空间的消耗,可以利用循环的方法来控制区间大小,为非递归方法实现归并排序的关键。与递归不同的是,非递归的单趟循环会使整个数组的相同小区间都变得有序,区间大小的两倍大于等于数组后,整个数组都有序。

代码:

// 归并排序非递归实现
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	// 归并每组数据个数,从1开始,因为1个认为是有序的,可以直接归并
	int rangeN = 1;
	while (rangeN < n)
	{
		for (int i = 0; i < n; i += 2 * rangeN)
		{
			// [begin1,end1][begin2,end2] 归并
			int begin1 = i, end1 = i + rangeN - 1;
			int begin2 = i + rangeN, end2 = i + 2 * rangeN - 1;
            //控制临时数组的下标
			int j = i;

			// end1 begin2 end2 越界
			// 修正区间  ->拷贝数据 归并完了整体拷贝 or 归并每组拷贝
			if (end1 >= n)
			{
				end1 = n - 1;
				// 不存在区间
				begin2 = n;
				end2 = n - 1;
			}
			else if (begin2 >= n)
			{
				// 不存在区间
				begin2 = n;
				end2 = n - 1;
			}
			else if (end2 >= n)
			{
				end2 = n - 1;
			}

			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, tmp, sizeof(int) * n);

		rangeN *= 2;
	}

	free(tmp);
	tmp = NULL;
}

特点

1.需要借助额外的数组,空间复杂度为O(N)

2.时间复杂度O(NlogN),数组的有序性不影响算法的效率。

3.分而治之思想的应用。

八、计数排序

 基本思想 

1.找到数组a的最大元素和最小元素,计算range = a[max]-a[min]+1,动态申请额外的数组空间tmp,长度为range,并初始化数组元素为0;

2.对以a[i]-min为下标的tmp元素+1,从而达到计数的效果。

3.遍历整个数组a,执行操作2,然后再将数组tmp中的元素下标+min拷贝回原数组,拷贝一个元素-1,值为0时拷贝下一个,直到tmp数组全为0,得到的拷贝数组即为排序后的数组。

实现

代码:

// 计数排序
void CountSort(int* a, int n)
{
	int min = a[0], max = a[0];
	for (int i = 0;i < n;i++)
	{
		if (a[i] < min)
		{
			min = a[i];
		}
		if (a[i] > max)
		{
			max = a[i];
		}
	}
	int range = max - min + 1;
	int* tmp = (int*)calloc(range, sizeof(int));
	if (tmp == NULL)
	{
		perror("calloc fail");
		exit(-1);
	}
	//1.计数
	for (int i = 0;i < n;i++)
	{
		tmp[a[i] - min]++;
	}
	//2.排序
	int i = 0;
	for (int j = 0;j < range;j++)
	{
		while(tmp[j] > 0)
		{
			a[i++] = j + min;
			tmp[j]--;
		}
	}
	free(tmp);
	tmp = NULL;
}

特点

1.非比较排序,不是通过数组元素之间进行比较来进行排序;

2.有局限性,适用于极差小的数组。数组元素越集中,算法的效率越高。

3.只适合整型,不能用于浮点数的排序。

4.时间复杂度O(N+range)

5.空间复杂度O(range)

九、排序算法的稳定性

排序算法的稳定性是指,对于未排序前的数组,排序后相同值的元素的相对位置有没有可能会发生改变;排序后,相同元素的相对位置不发生改变,则该排序算法是稳定的,反之亦然。

故,上述八大排序中,稳定排序有:直接插入排序、冒泡排序、归并排序、计数排序;

不稳定排序有:希尔排序、选择排序、堆排序、快速排序。

(只有在排序前相同元素的顺序有意义时,稳定性才有意义。)

meow_yao
关注 关注
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
算法数据结构课件PPT第八章
07-16
"算法数据结构课件PPT第八章" 本章节主要讲解了排序算法的基本概念和插入排序算法排序是将任意序列的一组记录按关键字升序或降序重新排列的过程。排序的基本概念包括记录的定义、记录的存储结构、排序的基本...
常用数据结构及其算法的Java实现
11-12
八大排序算法及其实现,具体包括直接插入排序,希尔排序,直接选择排序,堆排序,冒泡排序,快速排序,归并排序,基数排序在内的八种排序算法,同时对各种算法的基本特征做出了详细分析: - 算法基本思想 - 算法的...
数据结构——排序
m0_68373260的博客
12-02 633
数据结构,简单选择排序、直接插入排序、希尔排序、冒泡排序、快速排序 递归排序、堆排序、基数排序
C语言的升序排列
sunmo0n的博客
12-17 1万+
@TOCC语言中的排列 1,代码 //升序排列 #include<stdio.h> void sort(int array[],int n); //排序函数声明 void swap(int *ex1,int *ex2); //交换函数声明 int main() { int a[10],i; printf(“请输入要排列的数字:\n”); for(i=0;i<(sizeof a/sizeof a[0]);i++){ scanf("%d",&a[i]);} sort
数据结构中常用的7种排序方法
qq_51928118的博客
03-23 2974
`数据结构中常用的7种排序方法`
Python编程基础 第五章 编程练习 编写程序实现以下功能:使用选择排序算法将列表中的元素按照升序方式排列。
sxt1001的博客
10-07 2870
题目内容: 编写程序实现以下功能:使用选择排序算法将列表中的元素按照升序方式排列。假设列表中有n个元素,则选择排序算法处理过程: (1)从n个元素中找出具有最小值的元素,如果其不是第1个元素则将其与第1个元素交换。 (2)从后n-1个元素中找出具有最小值的元素,如果其不是第2个元素则将其与第2个元素交换。 ... (i)从后n-i+1个元素中找出具有最小值的元素,如果其不是第i个元素则将其与第i个元素交换。 ... (n-1)从后2个元素中找出具有最小值的元素,如果其不是第n-1个元素则将其与
Sql Server 中 Order by排序升序,降序)
印象
08-06 10万+
--AddTime 升序,ID 升序 select * from DS_Finance ORDER BY AddTime,ID; --AddTime 升序,ID降序 select * from DS_Finance ORDER BY AddTime,ID DESC; --AddTime 降序,ID升序 select * from DS_Finance ORDER BY AddTime DE...
排序算法的比较课程设计实验报告.pdf
06-07
实验中,我们使用 Microsoft Visual C++6.0 作为开发工具,生成 1000 个随机整数,并使用不同的排序算法对其进行升序排序。 三、 实验结果 实验结果显示,直接插入排序的时间复杂度最小,冒泡排序的时间复杂度最大...
数据结构 1800题》
12-27
数据结构 1800题》 第一章 绪论 一、选择题 1. 算法的计算量的大小称为计算的(B )。【北京邮电大学2000 二、3 (20/8分)】 A.效率 B....2. 算法的时间复杂度取决...10. 若将数据结构定义为一个二元组(D,R),...
计算机操作系统实验一:进程调度.pdf
12-22
四、主要的数据结构 * 进程控制块(PCB)结构体,包含进程名、到达时间、所需运行时间、已用CPU时间、进程状态等信息。 * 链表及队列,用于存储和管理进程控制块。 五、算法流程图 * 根据贪婪算法,每次将满足...
动态排序升序
Pwnpanda的博客
12-03 1467
假如不知道所需要排序的数字数量,这个时候就需要动态排一下序 #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int compare_integers(void const *a,void const *b) { register int const *pa = a; register int const *pb = b; return...
C# List.sort排序详解(多权重,升序降序)
dongfushu7972的博客
03-29 3738
很多人可能喜欢Linq的orderBy排序,可惜U3D里面linq在Ios上会报错,所以就必须使用list的排序。 其实理解了并不难 升序降序比较 sort有三种结果 1,-1,0分别是大,小,相等。 默认List的排序升序排序 如果要降序排序,也很简单,只需要在前面加一个负号 List<int> tmp = new List<i...
冒泡排序算法升序
g1607058603的专栏
03-15 3593
一、原理设数组的长度是length,重复的走访数组length-1次,每次从第i个元素开始,依次比较相邻的两个元素的大小,若后面的元素小于前面的元素,则将两个元素的顺序交换,因而,最小的元素会经由交换慢慢“浮”到数列的顶端。二、实现代码public class MaoPao {    public static int[] maoPao(int [] arr) {    for(int i=0;...
数据结构:顺序表实例--将两个升序排列的线性表A和B合并集为一个有序排列的线性表C,用顺序表实现。
weixin_65589140的博客
12-11 584
顺序表,冒泡排序,c语言
数据结构基础_对一个数组进行升序排序
沙漏哟
04-12 3773
#include #include #define MAX_SIZE 101 /** * 交换两个数 宏定义方式 * @param x 交换数1 * @param y 交换数2 * @param t 临时变量 */ #define SWAP(x,y,t) ((t) = (x), (x) = (y), (y) = (t)) void sort(int li
数据结构排序汇总
teasong的博客
12-28 882
排序概念: 排序稳定性: 排序方法分类: 排序算法性能评价: 插入排序:把一个关键字取出,与有序区进行比较后,插入指定位置,在其后的关键字移位,如扑克牌的排序。 直接插入排序:把要排序的关键字当成哨兵,用此哨兵与前面的数进行比较,达成要求后,插入,并向后移位,再把哨兵移动正确位置。void InsertSort(int a[]){ int i,j;
数据结构八大排序总结
一个金牛座 的程序员
04-23 8581
1、排序的概念:排序就是将一组数据按照一定的顺序,递增或递减排列起来。 2、排序的稳定性:对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和经过排序之后,没有改变。 3、内部排序与外部排序:内部排序指的是排序时需要将全部数据加载到内存中;外部排序是指所要排序的数据太大了不能同时在内存中进行。 4、八大排序:插入排序、希尔排序、选择排序、快速排序、冒泡排序、堆排序、归并排序、计数排...
数据结构--链表的排序详解
热门推荐
William
11-18 11万+
1、前言 前面两篇博客,我已经把线性表的两种基本的表示形式,做了一个基本的介绍和一些对比。但是,我突然发现在链表这里我缺少一个很重要的内容,那就是对我们的链表进行排序,其实,在连接两个链表的时候,就要求我们的那两个链表是有序的。2、链表排序—最简单、直接的方式(直接采用冒泡或者选择排序,而且不是交换结点,只交换数据域)//线性表的排序,采用冒泡排序,直接遍历链表 void Listsort(Nod
两种简单的数组排序算法:冒泡排序和直接选择排序升序
TroyFish的博客
08-28 4824
冒泡排序的基本思想是:面对一排数据,先从前往后两两比较,如果前一个数比后一个数大就交换两者的顺序,即第一个数和第二个数比,第二个数和第三个数比,……,倒数第二个数和最后一个数比,这样一轮下来以后最大的数就排到最后;接着把除去最大的数的该组数据进行同样的操作,直至这组数只剩下一个,排序结束。 以下为Java语言描述,JUnit单元测试@Test public void orderTest(){
数据结构八大排序算法c++
最新发布
01-01
数据结构中的八大排序算法,是指常见的八种用于对数据进行排序算法。这八种算法分别是冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序和基数排序。 冒泡排序是一种简单的排序算法,通过不断比较和交换相邻元素的位置,使得最大(或最小)的元素逐渐往后(或往前)移动。 选择排序是一种简单直观的排序算法,每次选择未排序序列中最小(或最大)的元素,放到已排序序列的末尾。 插入排序是一种简单直观的排序算法,将一个待排序的元素插入到已部分排序的数列中的合适位置。 希尔排序是一种改进的插入排序算法,通过将待排序数列分组,并对每个分组进行插入排序,然后逐渐减小分组规模,最后进行一次插入排序。 归并排序是一种分治思想的排序算法,将待排序数列不断分割成较小的数列,然后再将这些较小的数列按照顺序进行合并。 快速排序是一种分治思想的排序算法,通过选择一个中间的基准元素,将数列分割成两部分,然后分别对这两部分进行排序。 堆排序是一种利用堆这种数据结构排序算法,通过将待排序数列构建成一个大(或小)顶堆,然后逐步将堆顶元素与最后一个元素交换,并调整堆结构。 计数排序是一种非比较型的排序算法,通过统计待排序数列中每个元素出现的次数,然后依次输出即可。 基数排序是一种非比较型的排序算法,通过对待排序数列的每个位进行排序,依次从低位到高位进行。 这里简单介绍了八大排序算法的基本思想和实现方法。在实际应用中,不同的排序算法适用于不同的场景和要求,我们需要根据具体情况选择合适的算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 【C语言】如何动态申请一个二维数组(假设数组元素为int型) 6028
  • 【Linux】编辑器vim详解 5656
  • 【C语言】扫雷小游戏的代码实现 5596
  • 【Linux】gcc编译器 5435
  • 【C语言】辨析scanf()、gets()和getchar()函数的关系以及printf()、puts()和putchar()的异同 2862

最新评论

  • 【Linux】编辑器vim详解

    Codigger官方: 我是codigger平台的代表,非常欣赏您所著的《【Linux】编辑器vim详解》博文,您对vim编辑器的深入剖析和全面介绍,无疑为广大读者提供了宝贵的学习资源。最近,我们推出了一款全新的协作式编程工具——codigger,它集成了多种编辑器的优点,并加入了实时协作、版本控制等先进功能。我们相信,作为一个对编辑器有着深入研究的专家,您一定能够发现codigger的独特之处,并为我们提供宝贵的反馈和建议。因此,我们诚挚地邀请您来体验codigger,感受它带来的全新编程体验。如果您愿意,我们可以为您安排一次线上演示或提供试用账号,让您更深入地了解我们的产品。

  • 【C语言】辨析scanf()、gets()和getchar()函数的关系以及printf()、puts()和putchar()的异同

    mashiromylove: 不错的文章,使我的大脑旋转,爱来自湖北表情包

  • 【Linux】gcc编译器

    Obstervc: 对于初学Linux的我来说,非常浅显易懂,其他人讲的都太书面化。感谢博主!

  • 【C语言】如何动态申请一个二维数组(假设数组元素为int型)

    会笑的圆珠笔: 真实误人子弟。那是数组指针!不是指针数组。

  • 【C语言】如何动态申请一个二维数组(假设数组元素为int型)

    孤立无援胡图图: 博主的“总结”似乎有不准确的地方。 第三种方法中,int(*p)[4],如果把4换成一个变量,是无法编译通过的,也就是说,第三种方法,列数不能是变量。

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 【C++11】lambda表达式&包装器
  • 【C++11】右值引用和移动语义
  • 【Linux】进程信号
2023年24篇
2022年18篇

目录

目录

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司深圳高端网站设计报价南充网站改版驻马店网站优化推荐铁岭网站优化哪家好肇庆网站设计报价恩施网站建设设计南平高端网站设计推荐梧州设计公司网站推荐福州seo网站优化推荐赣州百度竞价报价霍邱网络营销推荐甘孜关键词排名包年推广价格本溪建设网站哪家好六安SEO按效果付费公司株洲网站优化推广公司延边阿里店铺托管多少钱丽江关键词排名包年推广临沂百度网站优化价格萍乡网站优化按天收费多少钱益阳网站设计报价随州百度网站优化排名推荐萍乡网站改版报价阳泉网站改版佛山至尊标王武威英文网站建设公司连云港百度竞价报价梧州网站推广系统推荐宁德至尊标王公司嘉兴网站排名优化价格常德阿里店铺托管价格歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化