笔试题资源整理(3)

二:几种常用的排序方法整理

1),冒泡排序和快速排序

 1 void BubbleSort(int *a,int size)//冒泡排序,时间复杂度O(n^2),空间复杂度为1,稳定
 2 {
 3     for(int i=0;i<size-1;i++)
 4         for(int j=size-1;j>i;j--)
 5         {
 6           if(a[j]<a[j-1])
 7           {
 8              Swap(a[j],a[j-1]);
 9           }
10         }
补充一个更好的:
bool flag = true;
for (int i = 1; i < length && flag; i++)
{
flag = false;
for (int j = 0; j < length - i; j++)
{
if (array[j] > array[j + 1]) // Ascending,升序,小数上浮,大数下沉
{
flag = true;

temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
} // 每一轮比较后,如果flag仍旧为false,则表明元素集合已全部排好序,可以提前结束整个排序过程
}
11 } 12 13 int Partition(int *a,int low,int high) 14 { 15 int temp=a[low]; 16 while(low<high) 17 { 18 while(low<high&&a[high]>temp) 19 high--; 20 a[low]=a[high];//如果不满足上面条件,即该数小于temp,那么就将它移到前面 21 while(low<high&&a[low]<temp) 22 low++; 23 a[high]=a[low];//如果大于temp,就将它移到后面 24 } 25 a[low]=temp;//此标记找到正确位置,跳出上述的while循环是low与high相等时 26 return low; 27 } 28 void Qsort(int *a,int low,int high) //快速排序是不稳定的。最理想情况算法时间复杂度O(nlog2n),最坏O(n ^2)。 29 { 30 int key; 31 if(low<high) 32 { 33 key=Partition(a,low,high); 34 Qsort(a,low,key-1);//递归调用 35 Qsort(a,key+1,high); 36 } 37 38 } 39 void QuickSort(int *a,int length)//快速排序,在冒泡排序的基础上改进。 40 { 41 //int length=sizeof(a)/4; 42 //printf("长度为:%d",length);//这是什么节奏,在这里面算长度会出错???居然是13? 43 Qsort(a,0,length-1); 44 }

2),插入排序和希尔排序

 1 void InsertSort(int *a,int size)//插入排序,时间复杂度O(n^2),空间复杂度为1,稳定
 2 {
 3     int temp,j;
 4     for(int i=1;i<size;i++)
 5         if(a[i]<a[i-1])
 6         {
 7             temp=a[i];
 8              j=i;
 9             do{
10                 a[j]=a[j-1];
11                 j--;
12             }while(j>0&&a[j-1]>temp);
13           a[j]=temp;//找到可以插入的位置
14         }
15         
16 }
17 
18 void SellSort(int *a,int length)//希尔排序,时间复杂度O(n^2),空间复杂度为1,不稳定(是插入排序的改进)
19 {
20     int step,j,k,temp;//step为增量
21     for(step=length/2;step>0;step/=2)
22     {
23         for(j=step;j<length;j++)
24         {
25             if(a[j]<a[j-step])
26             {
27               Swap(a[j],a[j-step]);
28             }
29         }
30     }    
31 }

3),选择排序和堆排序

 1 void SelectionSort(int *a,int size)//选择排序,时间复杂度O(n^2),空间复杂度为1,不稳定,对所有序列都是稳定的才算稳定排序。
 2 //举个例子,序列5 8 5 2 9,从小到大排序,我们知道第一遍选择第1个元素5会和2交换,
 3 //那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
 4 {
 5     int min;
 6     for(int i=0;i<size-1;i++)
 7     {
 8         min=i;
 9         for(int j=i+1;j<size;j++)
10         {
11             if(a[min]>a[j])
12             {
13                 min=j;
14                 Swap(a[i],a[min]);
15             }
16 
17         }
18 
19     }
20 
21 }
22 
23 
24 void Heapify(int *arr, int low, int high)//
25 {
26     int large;
27     int temp = arr[low];
28     large = 2 * low + 1;
29     while(large <= high)
30     {
31         if(large<high && arr[large]<arr[large+1])
32             large = large + 1;
33         if(temp > arr[large])
34             break;
35         else
36         {
37             arr[low] = arr[large];
38             low = large;
39             large = 2 * low + 1;
40         }
41     }
42     arr[low] = temp;
43 }
44 void HeapSort(int *a,int length)//堆排序,时间复杂度为O(nlogn),空间复杂度1,不稳定
45 {
46     int i;
47     for(i=length/2-1;i>=0;i--)
48     Heapify(a,i,length-1);//先建成大顶堆
49 
50     for(i=length-1;i>=0;i--)
51     {
52       Swap(a[0],a[i]);
53       Heapify(a,0,i-1);
54     }
55 }

4),归并排序和计数排序

 1 void Merge(int *a,int *b,int start,int mid,int end)//归并排序,时间复杂度为O(Nlogn),空间复杂度为O(n),稳定
 2 {
 3   int j,k;
 4   for(j=mid+1,k=start;(start<=mid)&&(j<=end);k++)
 5   {
 6       if(a[start]<=a[j])
 7           b[k]=a[start++];
 8       else
 9           b[k]=a[j++];
10   }
11   if(start<=mid)
12   {
13       for(;start<=mid;k++)
14           b[k]=a[start++];
15   }
16   if(j<=end)
17   {
18       for(;j<=end;k++)
19           b[k]=a[j++];
20   }
21   for(int i=0;i<k;i++)
22           a[i]=b[i];
23    
24 }
25 void MSort(int *a,int *b,int start,int end)
26 {
27     int mid;
28     if(start!=end)
29     {
30         mid=(start+end)/2;
31         MSort(a,b,start,mid);
32         MSort(a,b,mid+1,end);
33         Merge(a,b,start,mid,end);
34     }
35     else;
36 }
37 
38 
39 void CountSort(int *a,int size)//这个排序的方法总感觉有点牵强。。。
40 {
41     int temp[10]={0},j=0;
42     for(int i=0;i<size;i++)
43         temp[a[i]]++; //假如a的值是3,2,1,6,5,7,8,9,0,4,这就意味着temp下标为他们时,值都是1
44     for(i=0;i<10;i++)
45     {
46         while(0 != temp[i])
47         {
48             a[j] = i;
49             temp[i]--;
50             j++;
51         }
52     }
53 }

运行代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3 void Swap(int &a,int &b)
  4 {
  5     int temp=a;
  6     a=b;
  7     b=temp;
  8 }
  9 void BubbleSort(int *a,int size)//冒泡排序,时间复杂度O(n^2),空间复杂度为1,稳定
 10 {
 11     for(int i=0;i<size-1;i++)
 12         for(int j=size-1;j>i;j--)
 13         {
 14           if(a[j]<a[j-1])
 15           {
 16              Swap(a[j],a[j-1]);
 17           }
 18         }
 19 }
 20 void SelectionSort(int *a,int size)//选择排序,时间复杂度O(n^2),空间复杂度为1,不稳定,对所有序列都是稳定的才算稳定排序。
 21 //举个例子,序列5 8 5 2 9,从小到大排序,我们知道第一遍选择第1个元素5会和2交换,
 22 //那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
 23 {
 24     int min;
 25     for(int i=0;i<size-1;i++)
 26     {
 27         min=i;
 28         for(int j=i+1;j<size;j++)
 29         {
 30             if(a[min]>a[j])
 31             {
 32                 min=j;
 33                 Swap(a[i],a[min]);
 34             }
 35 
 36         }
 37 
 38     }
 39 
 40 }
 41 void InsertSort(int *a,int size)//插入排序,时间复杂度O(n^2),空间复杂度为1,稳定
 42 {
 43     int temp,j;
 44     for(int i=1;i<size;i++)
 45         if(a[i]<a[i-1])
 46         {
 47             temp=a[i];
 48              j=i;
 49             do{
 50                 a[j]=a[j-1];
 51                 j--;
 52             }while(j>0&&a[j-1]>temp);
 53           a[j]=temp;//找到可以插入的位置
 54         }
 55         
 56 }
 57 
 58 int  Partition(int *a,int low,int high)
 59 {
 60    int temp=a[low];
 61    while(low<high)
 62    {
 63        while(low<high&&a[high]>temp) 
 64            high--;
 65        a[low]=a[high];//如果不满足上面条件,即该数小于temp,那么就将它移到前面
 66        while(low<high&&a[low]<temp)
 67            low++;
 68        a[high]=a[low];//如果大于temp,就将它移到后面
 69    }
 70    a[low]=temp;//此标记找到正确位置,跳出上述的while循环是low与high相等时
 71    return low;
 72 }
 73 void Qsort(int *a,int low,int high) //快速排序是不稳定的。最理想情况算法时间复杂度O(nlog2n),最坏O(n ^2)。
 74 {
 75     int key;
 76     if(low<high)
 77     {
 78       key=Partition(a,low,high);
 79       Qsort(a,low,key-1);//递归调用
 80       Qsort(a,key+1,high);
 81     }
 82 
 83 }
 84 void QuickSort(int *a,int length)//快速排序,时间复杂度O(nlogn),空间复杂度O(logn),不稳定,在冒泡排序的基础上改进
 85 {
 86  //int length=sizeof(a)/4;
 87  //printf("长度为:%d",length);//这是什么节奏,在这里面算长度会出错???居然是13?
 88  Qsort(a,0,length-1);
 89 }
 90 
 91 void CountSort(int *a,int size)//这个排序的方法总感觉有点牵强。。。
 92 {
 93     int temp[10]={0},j=0;
 94     for(int i=0;i<size;i++)
 95         temp[a[i]]++; //假如a的值是3,2,1,6,5,7,8,9,0,4,这就意味着temp下标为他们时,值都是1
 96     for(i=0;i<10;i++)
 97     {
 98         while(0 != temp[i])
 99         {
100             a[j] = i;
101             temp[i]--;
102             j++;
103         }
104     }
105 }
106 
107 void Merge(int *a,int *b,int start,int mid,int end)//归并排序,时间复杂度为O(Nlogn),空间复杂度为O(n),稳定
108 {
109   int j,k;
110   for(j=mid+1,k=start;(start<=mid)&&(j<=end);k++)
111   {
112       if(a[start]<=a[j])
113           b[k]=a[start++];
114       else
115           b[k]=a[j++];
116   }
117   if(start<=mid)
118   {
119       for(;start<=mid;k++)
120           b[k]=a[start++];
121   }
122   if(j<=end)
123   {
124       for(;j<=end;k++)
125           b[k]=a[j++];
126   }
127   for(int i=0;i<k;i++)
128           a[i]=b[i];
129    
130 }
131 void MSort(int *a,int *b,int start,int end)
132 {
133     int mid;
134     if(start!=end)
135     {
136         mid=(start+end)/2;
137         MSort(a,b,start,mid);
138         MSort(a,b,mid+1,end);
139         Merge(a,b,start,mid,end);
140     }
141     else;
142 }
143 
144 void Heapify(int *arr, int low, int high)//
145 {
146     int large;
147     int temp = arr[low];
148     large = 2 * low + 1;
149     while(large <= high)
150     {
151         if(large<high && arr[large]<arr[large+1])
152             large = large + 1;
153         if(temp > arr[large])
154             break;
155         else
156         {
157             arr[low] = arr[large];
158             low = large;
159             large = 2 * low + 1;
160         }
161     }
162     arr[low] = temp;
163 }
164 void HeapSort(int *a,int length)//堆排序,时间复杂度为O(nlogn),空间复杂度1,不稳定
165 {
166     int i;
167     for(i=length/2-1;i>=0;i--)
168     Heapify(a,i,length-1);//先建成大顶堆
169 
170     for(i=length-1;i>=0;i--)
171     {
172       Swap(a[0],a[i]);
173       Heapify(a,0,i-1);
174     }
175 }
176 
177 void SellSort(int *a,int length)//希尔排序,时间复杂度O(n^2),空间复杂度为1,不稳定(是插入排序的改进)
178 {
179     int step,j,k,temp;//step为增量
180     for(step=length/2;step>0;step/=2)
181     {
182         for(j=step;j<length;j++)
183         {
184             if(a[j]<a[j-step])
185             {
186               Swap(a[j],a[j-step]);
187             }
188         }
189     }    
190 }
191 
192 int main()
193 {
194     int a[10]={3,2,1,6,5,7,1,9,0,4},b[10];
195     int length=sizeof(a)/4;//一个整型占四个字节
196     // int temp;
197     //BubbleSort(a,length);//冒泡
198     //SelectionSort(a,length);//选择
199     //InsertSort(a,length);//插入
200     //QuickSort(a,length);//快速
201     //CountSort(a,length);//计数
202     //MSort(a,b,0,length-1);//归并
203     //HeapSort(a,length);//堆排序
204      SellSort(a,length);//希尔排序
205     for(int j=0;j<10;j++)
206         printf("%d
",a[j]);
207     return 0;
208 }
View Code
作者:wj704    出处:http://www.cnblogs.com/wj204/   
原文地址:https://www.cnblogs.com/wj204/p/3341825.html