排序算法 快速排序l两种算法和堆排序
快排算法有两种 一种是算法导论里的改进的快排算法
另一种是清华那本数据结构中的古典快排算法。这里我们会看到他们在运行时间上的不同,而且古典快排竟然优于改进的快排
。呵呵 好了不多说 上代码吧 。
View Code
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<time.h> //时间计数头文件
4
5
6 int left(int i)
7 {
8 return 2*i;
9 }
10
11 int right(int i)
12 {
13 return 2*i+1;
14 }
15
16
17 void MAX_HEAPIFY(int arr[],int i,int heapsize) //调堆根函数,这名字自己YY的,基本原理就是让不合理的角色合理化,
18 { //能力小的往下降,能力大的做老大。
19 int l,r;
20 int largest;
21 int temp;
22 l= left(i);
23 r=right(i);
24 if(l<=heapsize&&arr[l]>arr[i]) //左孩子比较大那么暂记录左孩子 选他做准太子。
25 largest=l;
26 else
27 largest=i;
28 if(r<=heapsize&&arr[r]>arr[largest]) //右孩子更有实力,选他做准太子
29 largest=r;
30 if(largest!=i) //当权者arr【i】不是实力最大,则交换二者
31 {
32 temp =arr[largest];
33 arr[largest]=arr[i];
34 arr[i] =temp;
35 MAX_HEAPIFY(arr,largest,heapsize); //给以前的当权者找个归路
36 }
37
38 }
39
40
41 void BUILD_MAX_HEAP(int arr[],int heapsize) //建堆
42 {
43 int contrasize=int (heapsize/2); //数组建堆是下标为n/2+1,...,n 是叶子节点。
44 for(int i=contrasize;i>=1;i--)
45 MAX_HEAPIFY(arr,i,heapsize);
46
47 }
48
49 void HEAP_SORT(int arr[],int heapsize) //堆排序算法
50 {
51 clock_t start=clock(); //计时开始时钟变量
52 double duration; //程序消耗时钟个数。
53 int temp;
54 int equalsize=heapsize;
55 BUILD_MAX_HEAP(arr,heapsize); //首建堆,但是实际上为了初始化。仔细体味能感觉到
56 for(int i=heapsize;i>=2;i--)
57 {
58 temp =arr[i];
59 arr[i]=arr[1];
60 arr[1]=temp;
61 equalsize=equalsize-1;
62 MAX_HEAPIFY(arr,1,equalsize);
63 }
64 printf("排序后的结果是:\n");
65 for(int i=1;i<=heapsize;i++)
66 printf(" %d ",arr[i]);
67 clock_t finish=clock();
68 duration=(double)(finish-start)/CLOCKS_PER_SEC;
69 printf("堆排序的耗费时间为: %f\n",duration);
70 }
71
72 /*上面是堆排序,下面是快速排序的两个的版本*/
73
74
75 void exchange(int arr[],int i,int j) //交换数组里的两个元素,为了后面方便我故意挪出来的。
76 { //也算是减少内聚低耦合吧 自己都觉得自己太自恋了。
77 int temp;
78 temp =arr[i];
79 arr[i]=arr[j];
80 arr[j]=temp;
81 return ;
82 }
83
84 int partition(int arr[],int p,int r) //这是改进版的 就是圣经上的那个快排选分段标记的函数
85 {
86 int contra=arr[r];
87 int i,j;
88 i=p-1;
89 for( j=p;j<=r-1;j++) //核心代码 这个实际上下面的是区别是这个固定一头,后面的小于标准
90 { //则往这边靠,正是这个原因导致他不如古典的快排耗时短,后面运行结果将验证
91 if(arr[j]<=contra)
92 {
93 i=i+1;
94 exchange(arr,i,j);
95 }
96 }
97 exchange(arr,i+1,r);
98 return i+1;
99 }
100
101 int quicksort(int arr[],int p,int r) //快排函数主体 没什么好说的
102 {
103 int q;
104 if(p < r)
105 {
106 q=partition(arr,p,r);
107 quicksort(arr,p,q-1);
108 quicksort(arr,q+1,r);
109
110 }
111
112 return 0;
113 }
114
115
116 /* 上面是改进后快速排序算法,下面这个是快速排序的最早版本 实际上清华的那本什么数据结构上就这个*/
117
118 int hoarepartition(int arr[],int p,int r) //这是古典的快排
119 {
120 int contra=arr[p];
121 int i=p;
122 int j=r;
123 while(true)
124 {
125 for(;arr[j]>contra;j--); //注意哦 有个小分号看见没?
126 for(;arr[i]<contra;i++); //选择contra的左大与右小交换 这个是快排的核心两头动
127 if(i<j)
128 exchange( arr, i, j);
129 else
130 return j;
131
132 }
133
134 }
135
136
137 int hoarequicksort(int arr[],int p,int r) //快排主体没什么好说的 呵呵
138 {
139 int q;
140 if(p < r)
141 {
142 q=hoarepartition(arr,p,r);
143 quicksort(arr,p,q-1);
144 quicksort(arr,q+1,r);
145
146 }
147
148 return 0;
149 }
150
151
152 int initarr(int arr1[],int arr2[],int arrcol) //这个函数自己构思的 主要是为了便于后面对数组排序时
153 { //前一次排序算法对数组的影响不会殃及下一次别的算法对数组调用。
154 for(int i=1;i<=arrcol;i++)
155 {
156 arr1[i]=arr2[i];
157 }
158 printf("排序前的数组为:\n");
159 for(int i=1;i<=arrcol;i++)
160 printf(" %d ",arr1[i]);
161 printf("\n");
162 return 0;
163 }
164
165 int _tmain(int argc, _TCHAR* argv[]) //主函数没什么好说的 呵呵
166 {
167 time_t timer;
168 int number;
169 int choice;
170 clock_t start,finish;
171 double duration;
172 srand((unsigned) time(&timer));
173 printf("请输入你想排序的的随机数个数:");
174 scanf("%d",&number);
175 int *arraytest=new int[number+1]; //这个地方是为了克服VC的局限,不能申明
176 arraytest[0]=0; //未定义大小的数组,所以采用指针的形式先申明在转换数组
177 printf("待排序数组为:\n");
178 for(int i=1;i<=number;i++)
179 {
180 arraytest[i]=rand()%1000; //记得上次Cydelovy 大神给我说过随机生成,这次我就自己YY啦
181 printf(" %d ",arraytest[i]);
182 }
183 printf("\n");
184 int *arraycpy=new int[number+1];
185
186 for(int i=0;i<=number;i++)
187 {
188 arraycpy[i]=arraytest[i]; //保存数组副本。便于适合不用排序方法不影响时间。
189 }
190 printf("请输入您的操作 输入CTRL+c则推出:\n");
191 printf("1 堆排序 2 古典快速排序 3 改进的快速排序\n");
192 while(scanf("%d",&choice)!=EOF)
193 {
194 switch(choice)
195 {
196 case 1:
197 initarr(arraytest,arraycpy,number); //你永远不知道第几次进入这个case,进入前数组是什么样
198 HEAP_SORT(arraytest,number); //那你就有义务进行数组同一,对,不是统一。
199 break;
200 case 2: //下面同了啊 不讲了啊
201 initarr(arraytest,arraycpy,number);
202 start=clock();
203 hoarequicksort(arraytest,1,number);
204 printf("排序后的结果是:\n");
205 for(int i=1;i<=number;i++)
206 printf(" %d ",arraytest[i]);
207 finish=clock();
208 duration=(double)(finish-start)/CLOCKS_PER_SEC;
209 printf("\n古典快速排序的耗费时间为: %f\n",duration);
210 break;
211 case 3:
212 initarr(arraytest,arraycpy,number);
213 start=clock();
214 hoarequicksort(arraytest,1,number);
215 printf("排序后的结果是:\n");
216 for(int i=1;i<=number;i++)
217 printf(" %d ",arraytest[i]);
218 finish=clock();
219 duration=(double)(finish-start)/CLOCKS_PER_SEC;
220 printf("\n改进的快速排序的耗费时间为: %f\n",duration);
221 break;
222 default:
223 printf("\n输入错误 ");
224 break;
225 }
226
227
228
229
230 }
231 return 0;
232 }
声明:本博客所有文章均是本人原创,转载我会有说明,网上如果有雷同的文章,均取自本人其他一些博客,或者本博客。
本人还是一名学生,希望得到各位牛人的指点,同时非常心诚的向你学习。