您的位置:首页 > 其它

各种排序算法总结

2015-11-30 18:57 190 查看
1.插入排序

//插入排序
void inssort(int a[],int n) {
//一个元素天然就是排好序的,所以i从1开始循环
for (int i = 1; i < n; i++) {
//后面的比前面相邻的元素小,交换这两个元素
for (int j = i; j > 0 && (a[j] < a[j - 1]); j--)
swap(a[j], a[j - 1]);
}
}


2.冒泡排序

//冒泡排序
//第i次循环,保证前面i个元素是有序的

void bubsort(int a[], int n) {
for (int i = 0; i < n; i++) {
//j每次都从末尾开始循环,如果前面相邻的元素比后面大,就交换这两个元素,直至j=i为止
for (int j = n - 1; j>i; j--) {
if (a[j] < a[j - 1])
swap(a[j], a[j - 1]);
}
}
}


3.选择排序

//选择排序
//第i次循环找第i小的元素
void selection(int a[], int n) {
for (int i = 0; i < n - 1; i++) {
int min = i;
for (int j = i+1; j < n; j++) {
if (a[j] < a[min]) {
min = j;
}
}
swap(a[i], a[min]);
}
}


4.快速排序

int partition(int a[], int l, int r, int &pivot) {
while (l < r) {
while (a[l] < pivot)//找到a[l]>=pivot
l++;
while (r > l&&a[r] >= pivot)//找到a[r]<piovt
r--;
swap(a[l], a[r]);//交换a[l],a[r]
}//l和r相遇的位置就是划分点最后该待在的位置
return l;
}

//快速排序
void qsort(int a[], int i, int j) {
if (i>=j)
return;
//取哪个位置作为划分点
int pivotindex = (i + j) / 2;
//将划分点元素移到数目末尾
swap(a[pivotindex], a[j]);
//调用partition函数,保证k左边的元素比a[j]小,右边的元素比a[j]大(或者等于)
int k = partition(a, i, j, a[j]);
//将pivot移动到合适的位置
swap(a[k], a[j]);
//递归对pivot左右半边数组调用qsort函数
qsort(a,i,k-1);
qsort(a, k + 1, j);
}


5.归并排序

//归并排序
void mergesort(int a[],int l,int r) {
if (l >=r)
return;
int mid = (l + r) / 2;
//递归对左右半边进行排序
mergesort(a, l, mid);
mergesort(a, mid + 1, r);
//用于排序的辅助数组,其左半边和a[l->mid]一致,右半边则是a[r->mid],保证了中间大,两边小
int *temp = new int[r + 1];
//复制左半边的数组
for (int i = l; i <= mid; i++)
temp[i] = a[i];
//复制右半部分的数组,注意顺序要反过来
int j = mid + 1;
for (int i = r ; i > mid; i--) {
temp[j++] = a[i];
}
//从辅助数组两边,选择较小的那个数作为排序后的第k个元素
for (int i = l, j = r, k = l; k <= r; k++) {
if (temp[i] < temp[j])
a[k] = temp[i++];
else
a[k] = temp[j--];
}
}


6.堆排序

class max_heap {
public:
int *a;
int n;
int size;
max_heap(int a[], int n) {//构造函数
this->a = a;
this->n = n;
size = n;
//建堆
for (int i = n / 2-1; i > -1; i--)
siftdown(i);
}
void heapsort() {
while(n>0){//当剩余元素大于0个
swap(a[0], a[--n]);//当前最大的元素和数组末尾元素交换
siftdown(0);//对调换之后的根节点元素进行siftdown处理
}
}

void siftdown(int pos) {//l=2*pos+1,r=2*pos+2
while ((2 * pos + 1) < n) {
int l = 2 * pos + 1;
int r = l + 1;
if (r<n&&a[r]>a[l])//l代表叶子节点中较大的那一个的下标
l = r;
if (a[l] > a[pos]) {//如果根节点比叶子节点中较大的那个小
swap(a[l], a[pos]);//交换
pos = l;//继续处理下一层节点
}
else
break;
}
}
void print() {//输出数组中的所有元素
for (int i = 0; i < size; i++)
cout << a[i] << " ";
cout << endl;
}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: