目录
冒泡排序
每次将排好序的序列放到末尾
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);
}
}