排序、查找(数据结构)

一、排序算法

1、冒泡排序

  • 思路:按照约定的排序顺序,两两比较相邻的数据,如果反序则交换,直到没有反序的记录为止。
  • 算法复杂度:O(n^2)
  • 比较次数:(1 + 2 + 3 +…+ n-1) = n * (n – 1) / 2 次
/*************************************************************************
	> File Name: bubble.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 09时21分25秒
 ************************************************************************/
#include<stdio.h>

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))

//冒泡排序
void bubbleSort(int a[], int len)
{
	int i, j;
	int temp;
	int flag = 1;
#if 1
	//从前往后排
	for(i = 0; i < len - 1; i++)										
	{
		flag = 1;
		for(j = 0; j < len - 1 - i; j++)
		{
			if(a[j] > a[j + 1])
			{	
				flag = 0;
				temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
		if(1 == flag)
		{
			break;
		}
	}
#else
	//从后往前排
	for(i = 0; i < len - 1; i++)
	{
		flag = 1;
		for(j = len - 1; j > i; j--)
		{
			if(a[j] < a[j - 1])
			{
				flag = 0;
				temp = a[j];
				a[j] = a[j - 1];
				a[j - 1] = temp;
			}
		}
		if(1 == flag)
		{
			break;
		}
	}
#endif
}

int main()
{
	int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
	int i;
	//冒泡排序
	bubbleSort(a, ARRAYSIZE(a));
	for(i = 0; i < ARRAYSIZE(a); i++)
	{
		printf("%d\n", a[i]);
	}
	return 0;
}

2、归并排序

  • 思路:假设初始序列含有n 个记录,则可以看成是n 个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2 个长度为2 或1 的有序序列;再两两归并,…,如此重复,直至得到一个长度为n 的有序序列,操作步骤如下:
    1、将所要进行排序的序列分为左右两部分,如果如果要进行排序的序列起始元素下标为left,最后一个元素的下标为right,那么左右两部分的临界点下标为mid = (left + right) /2。
    2、将上面所得的两部分序列继续按照步骤1 进行划分,直到划分的区间长度为1。
    3、将划分结束后的序列进行归并排序,排序方法为对所分的n 个子序列进行两两合并,得到 n/2 或n/2+1个含有两个元素的子序列,再对得到的子序列进行合并,直至得到 一个长度为n 的有序序列。
  • 算法复杂度:O(nlogn)
  • 分析:每一次排序,都要将n 个数据扫描一遍,耗费O(n)的时间,由于归并一共要进行log2(n)次,所以最终时间为nlogn。
/*************************************************************************
	> File Name: mergeSort.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 10时31分06秒
 ************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))

static void merge(int a[], int left, int right)
{
	int mid = (left + right) / 2;
	int i = left;
	int j = mid + 1;
	int k = 0;

	int *temp = (int *)malloc(sizeof(int) * (right - left + 2));
	assert(temp);

	while(i < mid + 1 || j < right + 1)
	{
		if(i < mid + 1 && j < right + 1)
		{
			if(a[i] < a[j])
			{
				temp[k] = a[i];
				k++;
				i++;
			}
			else
			{
				temp[k] = a[j];
				k++;
				j++;
			}
		}
		else if(i < mid + 1)
		{
			temp[k] = a[i];
			k++;
			i++;
		}
		else
		{
			temp[k] = a[j];
			k++;
			j++;
		}
	}

	i = 0;
	for(j = left; j < right + 1; j++)
	{
		a[j] = temp[i];
		i++;
	}
	
	free(temp);
}

void mergeSort(int a[], int left, int right)
{
	int mid = 0;
	if(left == right)
	{
		return;
	}
	else
	{
		mid = (left + right) / 2;
		mergeSort(a, left, mid);
		mergeSort(a, mid + 1, right);
		merge(a, left, right);
	}
}

int main()
{
	int a[] = {1, 34, 95, 74, 6, 24, 4, 36, 83, 10};
	int i = 0;
	//归并排序
	mergeSort(a, 0, ARRAYSIZE(a) - 1);
	for(i = 0; i < ARRAYSIZE(a); i++)
	{
		printf("%d\n", a[i]);
	}
	return 0;
}

3、选择排序

  • 思路:每次从数据中选出一个最大值或最小值放在序列的起始位置,直到全部待排序的数据元素排序完。
  • 算法特点:交换移动数据的次数少,节约时间。
  • 算法复杂度:O(n^2)
  • 比较次数:无论最好最坏,都需要比较(1 + 2 + 3 +…+ n-1) = n * (n – 1) / 2 次
/*************************************************************************
	> File Name: selectSort.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 10时11分14秒
 ************************************************************************/
#include<stdio.h>

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))

void selectSort(int a[], int len)
{
	int i, j;
	int min, temp;
	
	for(i = 0; i < len - 1; i++)
	{
		min = i;
		for(j = i + 1; j < len; j++)
		{
			if(a[j] < a[min])
			{
				min = j;
			}
		}

		if(min != i)
		{
			temp = a[min];
			a[min] = a[i];
			a[i] = temp;
		}
	}
}

int main()
{
	int a[] = {1, 3 ,5, 7, 9, 2, 4, 6, 8, 10};
	int i;
	//选择排序
	selectSort(a, ARRAYSIZE(a));
	for(i = 0; i < ARRAYSIZE(a); i++)
	{
		printf("%d\n", a[i]);
	}
	return 0;
}

4、插入排序

  • 思路:每次从数据中选出一个数据插入到已经排好序的有序表中,从而得到一个新的,记录数增加1 的有序表(类比打扑克中一边摸牌,一边理牌的过程)。
  • 算法复杂度:O(n^2)
  • 比较次数:最好时,比较n-1 次;最坏时,比较2 + 3 +…+n = (n + 2)(n - 1)/2 次
/*************************************************************************
	> File Name: insertSort.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 10时31分06秒
 ************************************************************************/
#include<stdio.h>

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))

void insertSort(int a[], int len)
{
	int i, j;
	int temp, point;
	for(i = 1; i < len; i++)
	{
		point = i;
		for(j = i - 1; j >= 0; j--)
		{
			if(a[j] > a[point])
			{
				temp = a[j];
				a[j] = a[point];
				a[point] = temp;
				point = j;
				continue;
			}
			break;
		}
	}
}

int main()
{
	int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
	int i;
	//插入排序
	insertSort(a, ARRAYSIZE(a));
	for(i = 0; i < ARRAYSIZE(a); i++)
	{
		printf("%d\n", a[i]);
	}
	return 0;
}

5、简单排序

  • 思路:按照(从小到大或从大到小)的排序顺序,两两比较所有的数据,如果反序则交换 位置,直到比较完所有的数据。
  • 算法复杂度:O(n^2)
  • 比较次数:(1 + 2 + 3 +…+ n-1) = n * (n – 1) / 2
/*************************************************************************
	> File Name: simpleSort.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 17时01分46秒
 ************************************************************************/
#include<stdio.h>

void simpleSort(int a[], int len)
{
	int i, j;
	int temp;
	for(i = 0; i < len; i++)
	{
		for(j = i + 1; j < len; j++)
		{
			if(a[i] > a[j])
			{
				temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}
}

int main()
{
	int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
	int i = 0;
	//简单排序
	simpleSort(a, 10);
	for(i = 0; i < 10; i++)
	{
		printf("%d\n", a[i]);
	}
	return 0;
}

二、查找算法

1、二分查找(循环、递归)
二分查找也称折半查找,其优点是速度快,缺点是要求数据必须是有序列序列

/*************************************************************************
	> File Name: binarySearch.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 14时27分57秒
 ************************************************************************/

#include<stdio.h>

//循环形式的二分查找
//int binarySearchByLoop(int a[], int n, int key)
//{
//	int low = 0;
//	int high = n - 1;
//	
//	while(low <= high)
//	{
//		int mid = (low + high) / 2;
//		
//		if(a[mid] == key)
//		{
//			return mid;
//		}
//		else if(a[mid] < key)
//		{
//			low = mid + 1;
//		}
//		else
//		{
//			high = mid - 1;
//		}
//	}
//	return -1;
//}

//递归形式的二分查找
int binarySearch(int a[], int left, int right, int key)
{
	if(left > right)
		return -1;

	int mid = (left + right) / 2;
	if(a[mid] > key)
	{
		return binarySearch(a, left, mid - 1, key);
	}
	else if(a[mid] < key)
	{
		return binarySearch(a, mid + 1, right, key);
	}
	else
	{
		return mid;
	}
}

int main()
{

	int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int i = binarySearch(a, 0, 9, 9);
	printf("%d\n", i);

	return 0;
}

2、简单查找

/*************************************************************************
	> File Name: simpleSearch.c
	> Author: mrhjlong
	> Mail: mrhjlong@163.com 
	> Created Time: 2016年04月16日 星期六 17时19分47秒
 ************************************************************************/

#include<stdio.h>

int simpleSearch(int a[], int left, int right,int key)
{
	int i;
	for(i = left; i < right + 1; i++)
	{
		if(a[i] == key)
		{
			return i;
		}
	}
	return -1;
}

int main()
{
	int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int i = simpleSearch(a, 0, 9, 10);
	printf("%d\n", i);

	return 0;
}

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值