快速排序
本文整理我对快速排序的学习与理解。
时间复杂度好的情况下O(n*logn)最坏的情况下O(n*n)
对于一组序列 a[] = {6, 9,10, 8, 1, 19, 4};
1、选择第一个元素作为分界值temp,比temp大的数往右移,比temp小的数往左移,分为两类
2、把temp移到中间,其左右两个区间看做新的待排序的序列,重复第1步。
这是一个递归过程,直到区间长度为1,return;
【代码1(递归法)】:
#include<bits/stdc++.h>
using namespace std;
void Qsort(int *a,int low,int high)//[low,high]闭区间
{
if(low>=high)return;
int l=low,r=high;
int temp=a[l];//记下首元素,作为分界值
while(l<r)
{
while(l<r&&a[r]>=temp)r--;//右端点左移,直到值<temp,需要放到左边去
a[l]=a[r];
while(l<r&&a[l]<=temp)l++;
a[r]=a[l];
}
a[l]=temp;
Qsort(a,low,l-1);
Qsort(a,l+1,high);
}
int main()
{
int a[10]={49,38,65,27,79,98,12,42,100,9};
Qsort(a,0,9);
for(int i=0;i<10;i++)
printf("%d ",a[i]);
}
【代码2非递归】
#include<bits/stdc++.h>
using namespace std;
void Qsort(int *a,int n)
{
int l,r,low,high;
queue<int>q;
q.push(0);q.push(n-1);
while(!q.empty())
{
low=l=q.front();q.pop();
high=r=q.front();q.pop();
int temp=a[l];//记下首元素,作为分界值
while(l<r)
{
while(l<r&&a[r]>=temp)r--;//右端点左移,直到值<temp,需要放到左边去
a[l]=a[r];
while(l<r&&a[l]<=temp)l++;
a[r]=a[l];
}
a[l]=temp;
if(low<l-1){q.push(low);q.push(l-1);}
if(l+1<high){q.push(l+1);q.push(high);}
}
}
int main()
{
int a[]={4,8,2,8,10,5};
Qsort(a,6);
for(int i=0;i<6;i++)
printf("%d ",a[i]);
}
【代码3(递归法--单链表)】
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
//带有头结点的单链表快速排序算法
void LQSort(LinkList h,LinkList end){
//h所指结点不参与排序,h后继点作为分界结点
//end结点不参与排序,作为结束条件
//相当于开区间(h,end)排序
if(h->next==end)return;
LinkList pre=h, now=h->next;
while(now!=end){
if(now->data < h->next->data)
{
pre->next = now->next;
now->next = h->next;
h->next = now;
//上三句使用头插法将结点now转移到左边
now = pre->next;
}else{ //now本身就在右边,无需移动
pre = now;
now = now->next;
}
}
LQSort(h,h->next);
LQSort(h->next,end);
}
int main()
{
LinkList head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
int num;
printf("请输入若干个数字,输入0结束:\n");
scanf("%d",&num);
while(num!=0){
LinkList p = (LinkList)malloc(sizeof(LNode));
p->data = num;
p->next = head->next;
head->next = p;
scanf("%d",&num);
}
for(LinkList p=head->next;p!=NULL;p=p->next){
printf("%3d ",p->data);
}
printf("\n\n");
LQSort(head,NULL); //排序
for(LinkList p=head->next;p!=NULL;p=p->next){
printf("%3d ",p->data);
}
printf("\n\n");
}