排序算法总结(C语言版)

1.    插入排序

1.1     直接插入排序

1.2     Shell排序

2.    交换排序

2.1     冒泡排序

2.2     快速排序

3.    选择排序

3.1     直接选择排序

3.2     堆排序

4.    归并排序

4.1     二路归并排序

4.2     自然合并排序

5.    分布排序

5.1     基数排序

1.插入排序

1.1      直接插入排序

将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的部分中去。

代码:

/*
 * 直接插入排序,由小到大
 */
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
# define NUM 10

void InsertSort(int num[],int n)
{
	int i, j;
	int temp;

	for (i = 1; i < n; i++)
	{
		temp = num[i];
		for (j = i - 1; j >= 0 && num[j] > temp; j--)
		{
			num[j + 1] = num[j];
		}
		num[j + 1] = temp;
	}
}
void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	InsertSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d", num[i]);
}

1.2      Shell排序

先将整个待排记录序列分隔成若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

子序列选择:将相隔某个增量的记录组成一个序列。

“增量序列”选择注意事项:应使增量序列中的值没有除1之外的公因子,并且最后一个增量值必须为1。

代码:

/*
 * 希尔排序,由小到大
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NUM 10

void ShellSort(int num[], int n)
{
	int i, j, k;
	int temp;
	int inc;

	//增量序列为{5,2,1}
	for (inc = 5; inc >= 1; inc /= 2)
	{
		//如果增量为inc,则需要分成inc组进行直接插入排序
		for (k = 0; k < inc; k++)
		{
			for (i = k + inc; i < n; i += inc)
			{
				temp = num[i];
				for (j = i - inc; j >= 0 && num[j] > temp; j -= inc)
				{
					num[j + inc] = num[j];
				}
				num[j + inc] = temp;
			}
		}
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	ShellSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

2.交换排序

2.1      冒泡排序

代码:

/*
 * 冒泡排序,由小到大
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NUM 10

void BubbleSort(int num[], int n)
{
	int i, j;
	int temp;

	for (i = 0; i < n - 1; i++)
	{
		for (j = 0; j < n - i - 1; j++)
		{
			if (num[j] > num[j + 1])
			{
				temp = num[j];
				num[j] = num[j + 1];
				num[j + 1] = temp;
			}
		}
	}
}
void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	BubbleSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

2.2      快速排序

快速排序(Quick Sort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以达到整个序列有序。

设要排序的数组是A[0],……,A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为枢轴,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。

代码1:

/*
 * 快速排序,由小到大。
 * 利用快速排序的基本思想:枢轴左边的所有元素均不大于枢轴右边的所有元素。
 * 常规的做法是同时从后往前和从前往后遍历,直至head和tail指向同一个元素。
 * 此处的做法是只从前往后遍历,将比枢轴元素小的元素移动到枢轴之前。
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NUM 10

void QuickSort(int num[], int head, int tail)
{
	int temp;
	int pivot = head;
	int i,j;

	//一次划分,从head+1开始,将比枢轴元素小的元素移动到枢轴之前。
	for (i = head + 1; i <= tail; i++)
	{
		if (num[i] < num[pivot])
		{
			temp = num[i];
			for (j = i - 1; j >= pivot; j--)
			{
				num[j + 1] = num[j];
			}
			num[pivot++] = temp;
		}
	}

	//一次划分之后,将分成的两个序列分别进行快速排序。
	if (head != pivot && head != pivot - 1)
	{
		QuickSort(num, head, pivot - 1);
	}
	if (pivot != tail && pivot + 1 != tail)
	{
		QuickSort(num, pivot + 1, tail);
	}
}

void sort(int num[], int n)
{
	QuickSort(num, 0, n - 1);
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	sort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

代码2:

/*
 * 快速排序,由小到大。
 * 常规的做法:同时从后往前和从前往后遍历,直至head和tail指向同一个元素。
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NUM 10

/*
 * 一次划分函数。
 * 函数功能:将序列num[head]~num[tail]利用num[head]作为枢轴,分成两个子序列。
 * 且左边序列所有元素的值不大于右边序列所有元素的值。
 * 返回值:函数返回枢轴的位置。
 */
int Partition(int num[], int head, int tail)
{
	int temp = num[head];

	while (head != tail)
	{
		while (num[tail] >= temp && head != tail)
		{
			tail--;
		}
		num[head] = num[tail];
		while (num[head] <= temp && head != tail)
		{
			head++;
		}
		num[tail] = num[head];
	}
	num[head] = temp;

	return head;
}

void QuickSort(int num[], int head, int tail)
{
	int pivot;

	pivot = Partition(num, head, tail);
	if (head != pivot&&head != pivot - 1)
	{
		QuickSort(num, head, pivot - 1);
	}
	if (pivot != tail&&pivot + 1 != tail)
	{
		QuickSort(num, pivot + 1, tail);
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	QuickSort(num, 0, NUM - 1);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

3.选择排序

3.1      直接选择排序

代码:

/*
 * 直接选择排序,由小到大
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NUM 10

void SelectSort(int num[], int n)
{
	int i, j;
	int temp;

	for (i = 0; i < n - 1; i++)
	{
		for (j = i + 1; j < n; j++)
		{
			if (num[i] > num[j])
			{
				temp = num[i];
				num[i] = num[j];
				num[j] = temp;
			}
		}
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	SelectSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d", num[i]);
}

3.2      堆排序

堆:n个元素序列{k1,k2...ki...kn},当且仅当满足下列关系时称之为堆:

(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4...n/2)

若将和此次序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

若在输出堆顶的最小值之后,使得剩余n-1个元素的序列重建一个堆,则得到n个元素中的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。

问题:

1.      如何由一个无序序列建成一个堆?

2.      如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?

代码:

/*
 * 堆排序,由小到大
 * 由小到大排序时,建立的堆为大顶堆;
 * 由大到小排序时,建立的堆为小顶堆。
 */
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NUM 10

/*
 * 初始条件:num[root]~num[end]中除了num[root]外均满足堆的定义。
 * 函数功能:调整num[root],使得num[root]~num[end]为大顶堆。
 */
void HeapAdjust(int num[],int root,int end)
{
	int i;
	int temp;
	for (i = root * 2; i <= end; i *= 2)
	{
		if (i + 1 <= end && num[i + 1] > num[i])
		{
			i++;	//i指向左右子结点中的大者
		}
		if (num[root] >= num[i])
		{
			break;
		}
		else
		{
			temp = num[root];
			num[root] = num[i];
			num[i] = temp;
			root = i;
		}
	}
}

void HeapSort(int num[], int n)
{
	int i;
	int temp;

	//将原始无序序列调整为堆。最后一个结点的双亲结点为最后一个非终端结点。故从i=n/2开始建堆。
	for (i = n / 2; i >= 0; i--)
	{
		HeapAdjust(num, i, n - 1);
	}

	//将堆顶元素(未排序中的最大值)和未排序的最后一个元素交换位置;之后重新建堆。
	for (i = n - 1; i >= 1; i--)
	{
		temp = num[i];
		num[i] = num[0];
		num[0] = temp;
		HeapAdjust(num, 0, i - 1);
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	HeapSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

4.归并排序

4.1二路归并排序

归并:将两个(或两个以上)有序表合并成一个新的有序表。

假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然而两两归并,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,.....,如此重复,直至得到一个长度为n的有序序列为止。这种排序算法称为2路归并排序。

代码1:(递归形式的归并排序)

/*
 * 归并排序,由小到大
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#define NUM 10

/*
 * 函数功能:将已排好序的序列sourceArr[head~mid]和sourceArr[mid+1~tail]归并在一起,
 * 使整个序列有序。最终的有序序列存储在数组targetArr中。
 */
void Merge(int sourceArr[], int targetArr[], int head, int mid, int tail)
{
	int i, j, k;
	for (i = head,j = mid + 1,k = head; i <= mid && j <= tail; k++)
	{
		if (sourceArr[i] <= sourceArr[j])
		{
			targetArr[k] = sourceArr[i++];
		}
		else
		{
			targetArr[k] = sourceArr[j++];
		}
	}

	if (i <= mid)
	{
		for (; k <= tail; k++)
		{
			targetArr[k] = sourceArr[i++];
		}
	}

	if (j <= tail)
	{
		for (; k <= tail; k++)
		{
			targetArr[k] = sourceArr[j++];
		}
	}
}

/*
 * 归并排序(递归):
 * 如果head!=tail,则对sourceArr[head~mid]和sourceArr[mid+1~tail]分别进行归并排序,
 * 并将排序后的两个序列归并在一起,使整体有序。
 */
void MergeSort(int sourceArr[], int targetArr[], int head, int tail)
{
	int mid;
	int *tempArr;

	tempArr = (int *)malloc(sizeof(int)*(tail - head + 1));
	if (head == tail)
	{
		targetArr[head] = sourceArr[head];
	}
	else
	{
		mid = (head + tail) / 2;
		MergeSort(sourceArr, tempArr, head, mid);
		MergeSort(sourceArr, tempArr, mid + 1, tail);
		Merge(tempArr, targetArr, head, mid, tail);
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	MergeSort(num, num, 0, NUM-1);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

代码2:(非递归形式的归并排序)

/*
 * 归并排序(非递归),由小到大
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#define NUM 10

/*
 * 将2路有序序列归并为1路。形参中只有sourceArr,没有targetArr。
 */
void Merge(int sourceArr[], int head, int mid, int tail)
{
	int i, j, k;
	int *targetArr;

	targetArr = (int *)malloc(sizeof(int)*(tail - head + 1));

	for (i = head, j = mid + 1, k = 0; i <= mid&&j <= tail; k++)
	{
		if (sourceArr[i] > sourceArr[j])
		{
			targetArr[k] = sourceArr[j++];
		}
		else
		{
			targetArr[k] = sourceArr[i++];
		}
	}

	if (i <= mid)
	{
		for (; k < tail - head + 1; k++)
		{
			targetArr[k] = sourceArr[i++];
		}
	}

	if (j <= tail)
	{
		for (; k < tail - head + 1; k++)
		{
			targetArr[k] = sourceArr[j++];
		}
	}

	for (i = head,k = 0; i <= tail; i++,k++)
	{
		sourceArr[i] = targetArr[k];
	}
}

void MergeSort(int num[],int n)
{
	int interval;
	int head;

	for (interval = 2; interval <= n; interval *= 2)
	{
		for (head = 0; head + interval <= n; head += interval)
		{
			Merge(num, head, head + interval / 2 - 1, head + interval - 1);
		}
		Merge(num, head, head + interval / 2 - 1, n - 1);//处理head + interval > n的情况
	}
	Merge(num, 0, interval / 2 - 1, n - 1);//处理interval > n的情况
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	MergeSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

4.2 自然合并排序

自然合并排序是归并排序算法的一种改进。

自然合并排序:对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段。例如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段有{4,8},{3,7},{1,5,6},{2}。用一次对数组a的线性扫描就足以找出所有这些排好序的子数组段。然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6})。继续合并相邻排好序的子数组段,直至整个数组已排好序。

代码:

/*
 * 自然合并排序,由小到大
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#define NUM 10

int heads[NUM];

/*
 * 扫描数组,将已排好序的子数组段的段首加入数组heads中。
 * 函数返回段首的总数。
 */
int check(int num[], int n)
{
	int num_of_head = 1;
	int i;

	heads[0] = 0;
	for (i = 1; i < n; i++)
	{
		if (num[i] < num[i - 1])
		{
			heads[num_of_head++] = i;
		}
	}
	return num_of_head;
}

/*
 * 将2路有序序列归并为1路。
 */
void Merge(int sourceArr[], int head, int mid, int tail)
{
	int i, j, k;
	int *targetArr;

	targetArr = (int *)malloc(sizeof(int)*(tail - head + 1));
	for (i = head, j = mid + 1, k = 0; i <= mid&&j <= tail; k++)
	{
		if (sourceArr[i] > sourceArr[j])
		{
			targetArr[k] = sourceArr[j++];
		}
		else
		{
			targetArr[k] = sourceArr[i++];
		}
	}

	for (; i <= mid; k++, i++)
	{
		targetArr[k] = sourceArr[i];
	}

	for (; j <= tail; k++, j++)
	{
		targetArr[k] = sourceArr[j];
	}

	for (i = head,k = 0; i <= tail; i++, k++)
	{
		sourceArr[i] = targetArr[k];
	}
}

void MergeSort(int num[], int n)
{
	int num_of_head;
	int i;

	while (1)
	{
		num_of_head = check(num, n);
		if (num_of_head == 1)
		{
			break;
		}
		else
		{
			for (i = 0; i < num_of_head - 1; i += 2)
			{
				if (i + 2 <= num_of_head - 1)
				{
					Merge(num, heads[i], heads[i + 1] - 1, heads[i + 2] - 1);
				}
				else
				{
					Merge(num, heads[i], heads[i + 1] - 1, n - 1);
				}
			}
		}
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	MergeSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

5.分布排序

5.1 基数排序

第一步

以LSD为例,假设原来有一串数值如下所示:

73, 22, 93, 43, 55, 14, 28, 65, 39, 81

首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:


0


1


81


2


22


3


73   93   43


4


14


5


55   65


6


7


8


28


9


39

第二步

接下来将这些桶子中的数值重新串接起来,成为以下的数列:

81, 22, 73, 93, 43, 14, 55, 65, 28, 39

接着再进行一次分配,这次是根据十位数来分配:


0


1


14


2


22   28


3


39


4


43


5


55


6


65


7


73


8


81


9


93

第三步

接下来将这些桶子中的数值重新串接起来,成为以下的数列:

14, 22, 28, 39, 43, 55, 65, 73, 81, 93

这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。

LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。

代码1(LSD):

/*
 * 基数排序,由小到大。
 * 假设待排序数最多只有3位数。
 * 最低位优先基数排序(LSD)
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#include <string.h>

#define NUM 10

/*
 * 用于获取整数num的个位、十位、或者百位
 */
int getdigit(int num, int power)
{
	int result;

	switch (power)
	{
	case 1:result = num % 10; break;		//个位
	case 2:result = num % 100 / 10; break;	//十位
	case 3:result = num / 100; break;		//百位
	}
	return result;
}

void RadixSort(int num[], int n)
{
	int count[10] = {0};
	int *bucket;
	int i;
	int key;
	int digit;

	bucket = (int *)malloc(sizeof(int) * n);

	//key从1到3表示,依次比较个位、十位、百位。
	for (key = 1; key <= 3; key++)
	{
		//key=1时,count[0~9]分别表示个位数为0,1...,9的元素的数量
		for (i = 0; i < n; i++)
		{
			digit = getdigit(num[i], key);
			count[digit]++;
		}

		//key=1时,count[i]表示个位数为0~i的元素的总数量
		for (i = 1; i < n; i++)
		{
			count[i] = count[i] + count[i - 1];
		}

		//从后往前遍历序列,将元素放入对应的子桶中。从后往前是为了保证稳定性。
		for (i = n - 1; i >= 0; i--)
		{
			digit = getdigit(num[i], key);
			bucket[--count[digit]] = num[i];
		}

		for (i = 0; i < n; i++)
		{
			num[i] = bucket[i];
		}

		//count数组清零。
		memset(count, 0, sizeof(int) * 10);
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	RadixSort(num, NUM);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

代码2(MSD):

/*
 * 基数排序,由小到大。
 * 假设元素最高位3位数。
 * 最高位优先排序(MSD)。
 */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#include <string.h>

#define NUM 10

int getdigit(int num, int power)
{
	int result;

	switch (power)
	{
	case 1:result = num % 10; break;
	case 2:result = num % 100 / 10; break;
	case 3:result = num / 100; break;
	}

	return result;
}

void RadixSort(int num[], int head,int tail,int key)
{
	int i,j;
	int digit;
	int *bucket;
	int count[10] = {0};
	int count_backup[10];
	int left, right;

	bucket = (int*)malloc(sizeof(int)*(tail - head + 1));

	for (i = head; i <= tail; i++)
	{
		digit = getdigit(num[i], key);
		count[digit]++;
	}

	for (i = 1; i < 10; i++)
	{
		count[i] = count[i] + count[i - 1];
	}

	memcpy(count_backup, count, sizeof(int) * 10);	//备份count数组中的数据

	for (i = tail; i >= head; i--)
	{
		digit = getdigit(num[i], key);
		bucket[--count[digit]] = num[i];
	}

	for (i = head, j = 0; i <= tail; i++, j++)
	{
		num[i] = bucket[j];
	}

	free(bucket);

	if(key != 1)
	{
		//对每个子桶中的数据分别按下一位进行基数排序。
		key--;
		if (count_backup[0] != 0 && count_backup[0] != 1)
		{
			RadixSort(num, head, head + count_backup[0] - 1, key);
		}
		for (i = 0; i <= 8; i++)
		{
			left = head + count[i];
			right = head + count[i + 1] - 1;

			if (left < right)
			{
				RadixSort(num, left, right, key);
			}
		}
	}
}

void main()
{
	int num[NUM];
	int i;

	for (i = 0; i < NUM; i++)
		scanf("%d", num + i);

	RadixSort(num, 0, NUM - 1, 3);

	for (i = 0; i < NUM; i++)
		printf("%-3d ", num[i]);
}

pdf版下载:http://pan.baidu.com/s/1bn1XL3T

排序算法总结(C语言版),布布扣,bubuko.com

时间: 2024-10-09 07:05:55

排序算法总结(C语言版)的相关文章

常用排序算法的C语言实现

最近看数据结构,把常用的排序算法用C语言写了一下. 没有按数据结构上的定义SqList结构体,只是用数组的形式实现. 有的算法并没有完全按书上给出的算法,但思路一致. #include<stdio.h> void InsertSort(int[], int); //直接插入排序 无哨兵 void BInsertSort(int[], int); //折半插入排序 void BubbleSort(int[], int); //起泡排序 void QSort(int[], int, int); /

深入排序算法的多语言实现

深入浅出排序算法的多语言实现 作者:白宁超 2015年10月8日20:08:11 摘要:十一假期于实验室无趣,逐研究起数据结构之排序.起初觉得就那么几种排序,两三天就搞定了,后来随着研究的深入,发觉里面有不少东西.本文介绍常用的排序算法,主要从以下几个方面:算法的介绍.算法思想.算法步骤.算法优缺点.算法实现.运行结果.算法优化等.最后对本文进行总结.本文为作者原创,程序经测试无误.部分资料引用论文和网络材料以及博客,后续参见参考文献.(本文原创,转载注明出处) 1 排序的基本概念 排序: 所谓

【最全】经典排序算法(C语言)

本文章包括所有基本排序算法(和其中一些算法的改进算法): 直接插入排序.希尔排序.直接选择排序.堆排序.冒泡排序.快速排序.归并排序.基数排序. 算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首元素,并把它赋值给temp变量: 从排好的序列中,依次与temp进行比较,如果元素比temp大,则将元素后移(实际上放置temp的元素位置已经空出) 直到

排序算法(Java语言)——归并排序

归并排序mergesort中基本的操作是合并两个已排序的表.因为这两个表已排序,所以若将输出放到第三个表中,则该算法可以通过对输入数据一趟排序完成.基本的合并算法是取两个输入数组A和B,一个输出数组C,以及3个计数器Actr.Bctr.Cctr,他们初始置于对应数组的开始端.A[Actr]和B[Bctr]中的较小者被拷贝到C的下一个位置,相关的计数器向前推进一步.当两个输入表有一个用完的时候,则将另一个表中剩余部分拷贝到C中. 合并另个已排序的表的时间显然是线性的,因为最多进行N-1次比较,其中

几种经典排序算法的R语言描述

1.数据准备 # 测试数组 vector = c(5,34,65,36,67,3,6,43,69,59,25,785,10,11,14) vector ## [1] 5 34 65 36 67 3 6 43 69 59 25 785 10 11 14 2.R语言内置排序函数 在R中和排序相关的函数主要有三个:sort(),rank(),order(). sort(x)是对向量x进行排序,返回值排序后的数值向量; rank()是求秩的函数,它的返回值是这个向量中对应元素的“排名”; order()

排序算法总结(C++版)

总结下学过的排序算法,方便以后用到. 1.插入排序——将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表. void insertSort(int a[],int len) { for(int i = 1;i < len;i ++) { int j = i; int x = a[j]; //要插入的数 while(j > 0 && x < a[j - 1]) //将大的数推上去,空出个位置 { a[j] = a[j - 1]; j--; } a[j]

链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习

排序算法的C语言实现-快速排序

快速排序是在实践中最快的已知排序算法,它的平均运行时间是O(NlogN),该算法之所以特别的快,主要是由于非常精炼和高度优化的内部循环.它的最坏情形的性能为N^2. 快速排序由下列简单的四步组成: 1.如果S中元素个数是0或1,则返回. 2.取S中任以元素V,称之为枢纽元 3.将S分成俩个不相交的集合,前一个元素都小于V,后一个元素都大于V. 4.返回quicksort(S1)后,加上V,再加上quicksort(S2): 如何选取枢纽元? 有一种安全的方法是随机选取枢纽元,但是产生随机数的代价

常用七大排序算法总结(C语言描述)

目录 其中排序算法总结如下: 一.交换排序 交换排序的基本思想都为通过比较两个数的大小,当满足某些条件时对它进行交换从而达到排序的目的. 1.冒泡排序 基本思想:比较相邻的两个数,如果前者比后者大,则进行交换.每一轮排序结束,选出一个未排序中最大的数放到数组后面. #include<stdio.h> //冒泡排序算法 void bubbleSort(int *arr, int n) { for (int i = 0; i<n - 1; i++) for (int j = 0; j <