各种排序算法基于C的写法

目录

冒泡排序

选择排序

插入排序

希尔排序

归并排序

   快速排序

堆排序

大顶堆 


冒泡排序

每次将排好序的序列放到末尾

void swap(int a[],int i,int j)
{
	int t =a[i];a[i] = a[j];a[j] = t;
}

void bubble_sort(int a[],int n)
{
	for(int i= 1; i< n;i ++ )// 冒泡的次数
	for(int j=0;j < n-i;j ++ )
	if(a[j] > a[j + 1 ]) swap(a,j,j +1);

}

// 优化后的
void bubble_sort(int a[],int n)
{
	for(int i=1;i<n;i ++ )
	{
		bool isSorted = 1; 
		for(int j=0;j < n - i ;j ++)
			if(a[j] > a[j + 1 ]) 
			{
				swap(a,j,j+1);isSorted =0;
			}
		if(isSorted) return;	
	}
}

选择排序

每次选择最小的元素,放到最前

void selection_sort(int a[],int n)
{
	for(int i=0 ;i < n;i ++) // 选择的次序
	{
		int minIdx = i ;
		for(int j=i+1;j < n;j ++ )
			if(a[j] < a[minIdx])minIdx = j;
		swap(a,i,minIdx);
	}

}

插入排序

插入n-1次,每次将后面的无序区的元素插入到前面有序区中

当元素基本有序时,性能非常好

// 有序区 无序区
void insertion_sort(int a[],int n)
{
	//i 代表无序去的第一个元素
	for(int i=1;i < n ; i ++ )
	{
		int v= a[i];//j 开始位于有序区的最后一个元素
		int j =i - 1; 
		while(j >= 0 && a[j] > v)
		{
			a[j + 1 ] = a[j]; // 元素往后移动
			j -- ; 
		}
		a[j + 1 ] = v ;
	}
}

希尔排序

缩小增量排序(插入排序的改进版本)

// 将插入 排序中的1 换成变量 gap 
void shell_sort(int a[],int n)
{
	int gap = n /2 ;
	while(gap)
	{
		// 组内插入排序 
		for(int i= gap ; i < n ;i ++ )
		{
			int v = a[i];
			int j = i-gap;
			while(j >=0 && a[j] > v ) 
			{
				a[j+ gap] =  a[j]; j -= gap ;
			}
			a[j + gap] = v; 
		}
		//缩小增量
		gap >>= 1; 
	}

}

归并排序

// [l,mid][mid+1,r] 合并
void merge(int a[],int l,int mid,int r)
{
	int len = r - l + 1 ;
	int *t = (int*) malloc(len  * sizeof(int));
	if(t == NULL )
	{
		printf("Error: malloc failed in merge.\n");
		exit(1);
	}

	int i= l ,j = mid + 1 ,k = 0;
	while(i <= mid && j <= r )
	{
// 为了稳定性 不能写成 <  ,原来后面的数据本来应该在后面的,如果因为这里写成了< ,就会换到前面去
		if(a[i] <= a[j]) t[k ++ ] = a[i ++ ];
		else t[k ++ ] = a[j ++ ] ; 
	}
	while(i <= mid ) t[k ++ ] = a[i  ++ ] ;
	while(j <= r ) t[k ++ ] = t[j ++ ];

	// 复制数据
	for(int i=0 ;i < len ; i ++ )
		a[i+l] = t[i];
    free(t);
}

void merge_sort1(int a[],int l,int r)
{
	if(l >= r ) return;
	int mid = l + r >> 1; 
	merge_sort1(a,l,mid);
	merge_sort1(a,mid+1,r);
	merge(a,l,mid,r);
}

void merge_sort(int a[],int n)
{
	merge_sort1(a,0,n-1);
}

   快速排序

#include <bits/stdc++.h>
using namespace std;

const int N = 10;


void swap(int a[],int i,int j)
{
	swap(a[i],a[j]);
}


int partition(int a[],int l,int r)
{
	int pivot = a[l];
	int i = l, j = r;
	while(i < j )
	{
		while(i < j && a[j ] >= pivot) j -- ;
// i == j || a[j] < pivot 		
		a[i] = a[j];
		while(i < j && a[i] <= pivot) i ++ ;
		a[j] = a[i];
	}
//i ==j 
	a[i] =  pivot;
	return i;
}


void quick_sort1(int a[],int l,int r)
{
	if(l >= r ) return;
	//idx 为基准值的索引
	int idx = partition(a,l,r);
	quick_sort1(a,l,idx-1);
	quick_sort1(a,idx + 1 ,r);


}

void quick_sort(int a[],int n)
{
	quick_sort1(a,0,n-1);
}


int main()
{
	int n=5;
	int a[]={5,4,3,2,1};
		quick_sort(a,n);
	for(int i=0;i < n ;i ++ ) cout << a[i] << " \n"[i == n-1];

}


堆排序

大顶堆 


//i 可能不满足大顶堆性质的节点 ,len大顶堆包含的元素个数
void heapify(int a[],int i,int len)
{
	while(i < len )
	{

		int leftChild = 2 *i + 1 ;
		int rightChild = 2  *i + 2 ;

		int maxIdx = i; //  先假设当前根节点最大
		if(leftChild < len && a[leftChild] > maxIdx ) maxIdx = leftChild; 
		if(rightChild < len && a[rightChild] > maxIdx) maxIdx = rightChild;

		if(maxIdx == i ) break;
		swap(a,i,maxIdx);
		i = maxIdx;
	}
} 

// 2i + 1 <= n-1    ===> i <= (n-2)/2
void build_heap(int a[],int n)
{
//找到第一个非叶子结点
	for(int i= (n-2)/2 ;i >= 0;i -- )
	{
		heapify(a,i,n);
	}
}

void heap_sort(int a[],int n)
{
	//构建大顶堆
	build_heap(a,n);
	// 无序区的长度
	int len = n;

	while(len > 1 )
	{
		swap(a,0,len-1);len -- ; 
//把无序区重新调整为大顶堆
		heapify(a,0,len);
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值