笔试题资源整理(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\n",a[j]); 207 return 0; 208 }
作者:wj704
出处:http://www.cnblogs.com/wj204/