一、准备部分
1.数据存储结构:
#define MAXSIZE 1024
typedef int KeyType;
typedef struct {
KeyType key;
}RcdType;
typedef struct {
RcdType r[MAXSIZE + 1];
int length;
}Sqlist;
2.基本操作
包括对数据表的初始化、打印和排序时的元素交换,代码如下。
//数据结构打印
void print(Sqlist* list) {
for (int i = 1; i < list->length; i++) {
printf("%d ", list->r[i].key);
}
printf("%d\n", list->r[list->length].key);
}
//初始化数据存储结构
void initSqlist(Sqlist* list) {
int i = 0;
printf("请输入需要排序数据的个数:\n");
scanf("%d", &list->length);
printf("请依次输入数据:\n");
for (i = 1; i <= list->length; i++) {
scanf("%d", &list->r[i].key);
}
return;
}
//排序中的位置交换
void swap(RcdType *a, RcdType *b) {
RcdType temp = *a;
*a = *b;
*b = temp;
return;
}
二、排序算法
1.快速排序
快速排序的思想实质上就是将待排序的元素逐个归位。就比如一群不同身高的人站队,A站在第一位,他的身高第5高,那么就让班长1从队尾开始找比A高的人,找到以后,再让班长2从A的后一位开始找比A矮的人,将两人的位置调换。班长2不动,班长1接着找比高的人,找到以后不动,班长2接着找比A矮的人,找到后将两人位置调换……直到班长1与班长2相遇,让A与两位班长对应位置的人交换位置。这样就以A为界限,A前面全是比A高的人,A后面全是比A矮的人。你可能会问了:1.为什么是班长1先找,班长2后找?2.班长1、2相遇时对应位置的人一定不比A矮吗?
主要考虑相遇时出现的问题。我们发现相遇时无非是两种情况,班长1遇到不动的班长2或者班长2遇到不动的班长1。班长1先找:如果是班长1遇到不动的班长2时,他们所对应的数要么是这个数本身,要么是之前找到的比这个数大的数,把他与第一个数换没有问题。如果是班长2遇到不动的班长1时,班长1因为先动,指向的数一定比当前数大,所以也符合题意。班长2先找不和题意,留给大家自己分析。
对于算法的时间复杂度,第一次遍历整个链表n次,(假设每次相遇都在正中间)第二次遍历分别遍历n/2、n/2,第三次遍历fenbie遍历n/4、n/4、n/4、n/4……最后遍历到n/n为止,设一共遍历整个list m次,2的m次幂 = n,m = log2n ,所以时间复杂度为:m*n = nlog2n
,
代码如下:
void quickSort(Sqlist *list, int head, int tail) {
int i, j;
if (head >= tail)
return;
RcdType temp = list->r[head], t;
i = head;
j = tail;
while (i < j) {
while (list->r[j].key >= temp.key && i < j)
j--;
while (list->r[i].key <= temp.key && i < j)
i++;
if (i < j) {
swap(&list->r[i], &list->r[j]);
}
}
list->r[head] = list->r[i];
list->r[i] = temp;
quickSort(list, head, i - 1);
quickSort(list, i + 1, tail);
return;
}
void swap(RcdType *a, RcdType *b) {
RcdType temp = *a;
*a = *b;
*b = temp;
return;
}
补充了一段java版本的快速排序
import java.util.Random;
public class quick_sort {
public static void main(String[] args) {
int []arr = new int[]{5,6,9,8,2,3};
quickS(arr,0,arr.length-1);
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
public static void quickS(int []arr,int begin,int end){
if(begin == end || end - begin < 2)
return ;
int left = begin;
int right = end;
Random random = new Random();
int ran = random.nextInt(end - begin) + begin;
int baseValue = arr[ran];
swap(arr,ran,end);
int i = 0;
while(i < right){
if(arr[i] < baseValue){
swap(arr,i,left);
i++;
left++;
}
else if(arr[i] ==baseValue){
i++;
}
else {
right--;
swap(arr,i,right);
}
}
swap(arr,end,right);
quickS(arr,begin,left);
quickS(arr,right+1,end);
}
public static void swap(int []arr,int childIndex, int parentIndex){
int a;
a = arr[childIndex];
arr[childIndex] = arr[parentIndex];
arr[parentIndex] = a;
}
}
排序的时间复杂度:O(n*logn)
空间复杂度:O(logn) ->递归过程浪费的空间