[c语言编程]排序法汇总-入门级别(1)

声明,学习排序过程参考了极客学院视频教程,链接如下。

http://www.jikexueyuan.com/course/2542.html

分析问题解决问题的部分为原创。


每个排序都有不同应用场景。

红色,问题;

蓝色,技术要点;

绿色,完成结果,其他。


(一)冒泡法,插入,快速

(1)冒泡排序,乱序 到 顺序。

问题00:时间复杂度,稳定否?最差O(n^2);

方法:看做气泡,大气泡向上跑。每遍历一次,最大值排到最前边。结果: 由大到小排序。

                 头文件,iosstream,vector,没有.h

                 函数体,(大到小)

void Bulldle2(int *array , int num)  //函数声明格式问题1;

void Bulldle(int * array, int num)//数组指针,元素个数。遍历次数num-1

{

int i,j,temp;

for(i=0;i<num-1;i++)

{

for (j=i+1;j<num;j++)

if(array[i]<array[j])

{

temp=array[i];

array[i]=array[j];

array[j]=temp;

}

}

}


int main()

{

int array[]={7,5,3,9,1,3};//数组赋值方法,注意5

Bulldle(array,6);//传递参数格式,注意6

int i;

for(i=0;i<sizeof(array)/sizeof(int);i++)

cout<<array[i]<<endl;//cout,endl问题2;std::cout<<array[i]<<std::endl;//环境Xcode Mac

return 0;

}


//[优化1] 若后面元素已经置位,则不需要进一步排序。

void Bulldle2(int *array , int num)

{

int i,j,temp;

int flag=1;

for(i=0;i<num-1&&flag;i++)

{

flag=0;

for(j=i+1;j<num;j++)

if(array[i]>array[j])//小于号还是大于号,直接决定了,从小到大还是从大到小,i代表前面一个,j代表后面一个,前大于后交换,则从小到大,反之,从大到小。

{

temp=array[i];

array[i]=array[j];

array[j]=temp;

flag=1; //flag 意义,每次i外循环,循环所有数据,当不发生交换时,意味着后面的全部满足从小到大,也就不需要进行下一次循环了。

}

}

}



问题00:时间复杂度,稳定否?最差O(n^2);

【答】

使用.c,endl报错;原因是cpp文件。

问题0:C与cpp区别?

【答】

另外,c中无iosstream。【是iostream,打错】。

问题1:函数声明方法,最后有无分号?

【答】

问题2:cout,警告,程序建议修改为std::cout;endl,同理。std代表什么。注意箭头朝向cout。

【答】

注意3:for(a,b,c)里面习惯性写了逗号,应该是分号。(受Matlab影响)

注意4:头文件中,#include <iostream> #include <vector>, 并没有.h

注意5:int array[]={7,5,3,9,1,3};//数组赋值方法,不带指针符号,传递函数两个,第一个*array就代表数组第一个元素,第二个代表数组长度。

            大括号{1,2,3}形式。

注意6:传递参数格式。

X注意7:数组中有12个整数的时候,会报错。原因,中文输入法逗号。55555555TAT

修改后,成功排序。


(2)插入排序

问题:思想,时间复杂度,稳定性

思想:已排序好的序列,插入一个外来的元素。


实现:

c++

头文件,iostream,using namespace std;//何意


void InsertSort(int *array,int n)

{

int i,j;

int temp;


//从第二个元素开始进行插入操作,为其在前面排序好的序列中找到位置

for(i=1;i<n;i++)


temp=array[i];


for(j=i-1;j>=0;j--) //for循环解释,外循环从i=第2个元素开始,j遍历已排序好的倒序,找到第一个比array[i]小的,把array[i]放在此值之后。

{

if(array[j]>temp) //所有大于temp值的,向后移一位,腾出空间。继续比较。

array[j+1]=array[j];

else 

break;

}

//插入合适位置

array[j+1]=temp;//擅自增加的大括号{},之前位置加错,导致无法正常排序。

//另外,注意这里是把temp的值赋给小值之后的位置,而不是array[i],因为array[i]已经被array[i-1]占据,它已不再是原来的配方啦~


for(i=0;i<n;i++)

cout<<array[i]<<endl;

}


int main()

{

int array[]={5,4,7,8,9};

int n=sizeof()/sizeof(int);

InsertSort(array,n);//忘了加两个分号= =

}

问题1:using namespace std;//何意


---------------------------------------------------------------------------20160605未完待续--------------------------------------------------------------------------------------------------------------------------------------


(3)快速排序

思想,时间复杂度


总体思想都是相似的:

(1)确立基准值,比基准值小的部分,放在左边,比基准值大的部分放在右边;确定基准值的新位置;

(2)以新位置为界,左边组成子序列1,头-基准值位置;右边组成子序列2,基准值位置-尾;

(3)子序列按照相同思想排序。

(4)结束条件,头尾相等,或者说,头>尾。


假设有一个元素可以将整个数组,分成两个子数组,前面小于基准点,后面大于基准点。

递归调用。一直递归,直至某个子数组<=1个元素。


a)基准点概念;b)递归调用

字符串处理过程中使用过,基准点概念。

c语言实现1

#include <stdio.h>

#include<stdlib.h>


第一种分割方法----------------------------------------------------------------------------------------------

//int partition(int *array,int left, int right)       //本例子第一轮中,left=array[0]=9;right=array[8]=6

//{

//    int key=array[right]; //以最后一个元素为基准点,6

//    int i=left-1;               //i=0-1=-1;

//    int temp;

//    //开始以基准点为标准分割序列,j遍历的当前元素,i小于当前点的最后一个元素《字符串处理课程》

//    for(int j=left;j<right;j++)     //j=0,0<8.

//    {

//        if(array[j]<key)            //array[0]=9>6,不满足小于号条件,则不执行花括号内容,j=j+1=1;array[1]=4<6,执行花括号内容;j=2,5<6;j=4,1<6

//        {

//            i++;                    //i=-1+1=0,互换i,j值;{495213786};{452139786};i=4

//            

//            temp=array[j];

//            array[j]=array[i];

//            array[i]=temp;

//        }

//    }

//    //将基准点放在合适的位置           //把基准值6,放在第6位,array[4+1],{4,5,2,1,3,6,9,7,8}

//    temp=array[i+1];

//    array[i+1]=array[right];

//    array[right]=temp;

//    return i+1; //返回基准点所在位置的下标

//    

//}

//


//第二种分割方法---------------------------------------------------------------------------------------------------------------------------------------------

//交换函数

void swap(int *a,int *b)

{

    int temp=*a;

    *a=*b;

    *b=temp;

}


//分割函数

int partition(int *array,int low,int high)

{

    int key=array[low];

    while(low<high)

    {

        //从后面找到一个合适的值和前面交换,

        while(low<high&&array[high]>=key)

            high--;

        swap(&array[low],&array[high]);

        while(low<high&&array[low]<=key)

            ++low;

        swap(&array[low],&array[high]);

    }

    return low;

}

//递归过程1---------------------------------------------------------------------------------------------------------------------------------------------

void quicksort(int *array,int left,int right)

{

    if(left<right)

    {

        int k=partition(array,left,right);

        quicksort(array,left,k-1);         //基准值3,前半部分{21345};基准值1{12345}

        quicksort(array,k+1,right);        //基准值8,后半部分{789};;基准值9{789}k=8,k+1=9,left(9)>right(8)递归结束

    }

}







//第二种快速排序方法---------------------------------------------------------------------------------------------------------------------------------------------


//void quicksort2(int *array,int left,int right)

//{

//    int i,j,key;

//    if(left<right)

//    {

//        i=left;                                                         //按如下实例,i=0,j=12,k=array[0]=9;

//        j=right;

//        key=array[i]; //以最左边的元素作为分割基准点

//        do{

//            while(array[j]>key && i<j)               //以下进入嵌套循环,第一层,判断ij不等,第二层循环第一个,如果右边的数比基准值大,且i<j,则不动,j--

//                j--; //从右向左找第一个小于基准值的位置j

//            if(i<j) //找到了位置j                                    //直到在右边找到第一个,比基准值小的数字,就把[j]值给[i]i++;

//            {

//                array[i]=array[j];

//                i++;

//            } //将第j个元素置于左端并重置i

//            while(array[i]<key&&i<j)  //问题,一个是大于号,一个是小于号啦。代表小数左移,大数右移。                                      

///第二层循环第二个,如果左边的数比基准值小,且i<j,则不动,j++

//

//                i++; //从左向右找第一个大于标准的位置i

//            if(i<j)                                                         //直到在左边找到第一个,比基准值大的数字,就把[i]值给[j]j--;

//            {

//                array[j]=array[i];

//                j--;

//            }

//        } //将第i个元素置于右端并重置j

//        while(i!=j);

//            array[i]=key;

//        quicksort2(array,left,i-1);

//        quicksort2(array,i+1,right);

//    }

//}


//按照第2种快速排序方法。比基准值小的,去左边,比基准值大的,去右边;定位基准值;头-基准值位置,为第一子序列;基准值位置-尾,为第二子序列。

//

//

//建议复习字符串处理课程。

int main()

{

    int array[]={6,4,5,2,1,3,7};

    int n=0;

    n=sizeof(array)/sizeof(int);

    quicksort(array,0,n);

    int i;

    for(i=0;i<n;i++)

        printf("%d\n",array[i]);

    return0;

}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值