找工作-基本查找排序算法总结

每次找工作都感觉要复习下这些东西,常常想,这些神奇的玩意怎么就被想出来的!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1,常见排序算法:

排序的分类就不写了,各种分类,其实常用的就那么几种。

1.1  插入排序:

void insert_sort(int *a, int len) {
	int tmp;
	for (int i = 1; i < len; ++i) {
		for (int j = i; j > 0; --j) {
			if (a[j] < a[j-1]) {
				tmp = a[j];
				a[j] = a[j-1];
				a[j-1] = tmp;
			}
			else {
				break;
			}
		}
	}
}

平均和最差时间代价均为θ(n²)

1.2 冒泡排序:

void bubblesort(int *a, int len) {
	int tmp,j,k;

	k = len;
	int flag = true;
	while (flag) {
		flag = false;
		for (j = 1; j < k; ++j) {
			if (a[j-1] > a[j]) {
				tmp = a[j-1];
				a[j-1] = a[j];
				a[j] = tmp;
				flag = true;
			}
		}
		--k;
	}
}
该改进版来自: 点击打开链接

平均和最差时间代价均为θ(n²)

1.3 选择排序;

void selectsort(int *a, int len) {
	int tmp,index;
	for (int i = 0; i < len; ++i) {
		index = i;
		for (int j = i+1; j < len; ++j) {
			if (a[j] < a[index]) {
				index = j;
			}
		}
		if (index != i) {
			tmp = a[i];
		    a[i] = a[index];
		    a[index] = tmp;
		}
		
	}
}

平均和最差时间代价均为θ(n²)

备注:选择排序 是对 冒泡的改进,它使用了一个索引记录比较的结果,在一论遍历结束时才执行一次交换。

所以,对于交换代价比较大的问题,效果很明显。


1.4 shell排序

void insertsort_ex(int *a, int len, int incr) {
	int tmp;
	for (int i = incr; i < len; i += incr) {
		for (int j = i; j >= incr; j -= incr) {
			if (a[j] < a[j-incr]) {
				tmp = a[j];
				a[j] = a[j-incr];
				a[j-incr] = tmp;
			}
			else {
				break;
			}
		}
	}
}

void shellsort(int *a, int len) {
	for (int i = len/2; i > 2; i /= 2) {
		for (int j = 0; j < i; j++) {
			insertsort_ex(&a[j],len-j,i);
		}
	}
	insertsort_ex(a,len,1);
}

shell排序利用了插入排序的最佳性能,首先将序列变成基本有序,最后再用插入排序。

shell排序 增量的选择很重要,参考点击打开链接

1.5 快速排序

int partition(int *a, int l, int r) {
	int low = l;
	int hi = r;
	int pivot = a[low];
	for (;low < hi;) {
		
		while(low < hi && a[hi] >= pivot)
			--hi;
		a[low] = a[hi];

		while(low < hi && a[low] <= pivot)
			++low;
		a[hi] = a[low];
	}

	a[low] = pivot;
	return low;
}

void qsort(int *a, int low, int high) {
	if (low < high) {
		int p = partition(a,low,high);
		qsort(a,low,p-1);
		qsort(a,p+1,high);
	}
}

最差 O(n²),平均:θ(nlogn)

ps:可以改成尾递归形式。


1.6 堆排序

void HeapAdjust(int *a,int i,int size)  //调整堆 
{
	int lchild=2*i+1;       //i的左孩子节点序号 
	int rchild=2*i+2;     //i的右孩子节点序号 
	int max=i;            //临时变量 
	if(i<=(size-1)/2)          //如果i是叶节点就不用进行调整 
	{
		if(lchild<size&&a[lchild]>a[max])
		{
			max=lchild;
		}    
		if(rchild<size&&a[rchild]>a[max])
		{
			max=rchild;
		}
		if(max!=i)
		{
			swap(a[i],a[max]);
			HeapAdjust(a,max,size);    //避免调整之后以max为父节点的子树不是堆 
		}
	}        
}

void BuildHeap(int *a,int size)    //建立堆 
{
	int i;
	for(i=(size-1)/2;i>=0;i--)    //非叶节点最大序号值为size/2 
	{
		HeapAdjust(a,i,size);    
	}    
} 

void HeapSort(int *a,int size)    //堆排序 
{
	int i;
	BuildHeap(a,size);
	
	for(i=size-1;i>=1;i--)
	{
		//cout<<a[1]<<" ";
		swap(a[0],a[i]);           //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面 
		//BuildHeap(a,i-1);        //将余下元素重新建立为大顶堆 
		HeapAdjust(a,0,i);      //重新调整堆顶节点成为大顶堆
	}
} 
上述代码参考http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
不过我做了两处修改:修改为最大堆,升序输出;

修改根节点和孩子节点的对应关系,这样根节点保存在数组的第一个位置。

最佳、平均、最差时间代价都为O(n*logn);

引用:“堆排序其实也是一种选择排序,是一种树形选择排序。只不过直接选择排序中,为了从R[1...n]中选择最大记录,需比较n-1次,然后从R[1...n-2]中选择最大记录需比较n-2次。事实上这n-2次比较中有很多已经在前面的n-1次比较中已经做过,而树形选择排序恰好利用树形的特点保存了部分前面的比较结果,因此可以减少比较次数。对于n个关键字序列,最坏情况下每个节点需比较log2(n)次,因此其最坏情况下时间复杂度为nlogn。堆排序为不稳定排序,不适合记录较少的排序”

1.7 归并排序

//将有二个有序数列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{
	int i = first, j = mid + 1;
	int m = mid,   n = last;
	int k = 0;
	
	while (i <= m && j <= n)
	{
		if (a[i] <= a[j])
			temp[k++] = a[i++];
		else
			temp[k++] = a[j++];
	}
	
	while (i <= m)
		temp[k++] = a[i++];
	
	while (j <= n)
		temp[k++] = a[j++];
	
	for (i = 0; i < k; i++)
		a[first + i] = temp[i];
}
void mergesort(int a[], int first, int last, int temp[])
{
	if (first < last)
	{
		int mid = first + (last - first) / 2;
		mergesort(a, first, mid, temp);    //左边有序
		mergesort(a, mid + 1, last, temp); //右边有序
		mergearray(a, first, mid, last, temp); //再将二个有序数列合并
	}
}

bool MergeSort(int a[], int n)
{
	int *p = new int[n];
	if (p == NULL)
		return false;
	mergesort(a, 0, n - 1, p);
	delete[] p;
	return true;
}

归并排序最佳、平均、最差时间代价都为O(n*logn),该排序不太适合内存排序,因为不仅要开辟额外的线性内存,而且还要来回拷贝数据,想想还是算了吧。。。。

但是,归并排序是稳定的哦。

但是,归并排序中的merge是很多外部排序的基础哦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值