黑马程序员---c语言排序算法综合整理

-----------android培训java培训、java学习型技术博客、期待与您交流!------------ 

#include"stdio.h"

#include "stdlib.h"
#include "string.h"


struct Student_date 
{
int stu_num ;
int stu_score;
int stu_class;
char stu_name[20];
}
stu[]={ {2045,45,1,"wangwei"},{2041,98,2,"majun"},{2022,78,2,"huangwei"},
{2003,85,3,"liutao"},{2091,23,3,"zhangheng"},{2011,69,1,"lvjia"},
{2034,59,1,"tianliang"},{2022,78,3,"peijun"},{2009,23,2,"wanghan"},
{2045,41,3,"mating"}}; //结构体定义并初始化


#define  str_size (int)(sizeof(stu)/sizeof(struct Student_date)) //宏定义结构体大小  (重点记住方法)


typedef Student_date my_student_data;//重新声明结构体名称
my_student_data *ptr = NULL ,*temp = NULL;
void int_sort();//


//void show_students_message();
void stu_sort();//对九个学生的成绩进行冒泡排序
void index_sort();//索引排序
void ptr_sort();//指针排序
void put_student_int(int i);//通过下标输出学生信息
void put_student(Student_date* stu);//传递结构体参数,输出所有学生信息
void qsort_stdlib();//快速排序




void qsort_stdlib_intsort();//快速排序一个整形数组实例
bool compare_num(int *l, int *r);//快速排序一个整型数组的算法
int compare_qsort_num(const void* left, const void* right);//快速排序的算法原型


int  main()
{
//stu_sort();//1.冒泡排序  对学生信息排序
//int_sort();//对整型数组排序


//index_sort();//2.索引排序


ptr_sort();//3.指针排序


//qsort_stdlib();//4.快速排序
//qsort_stdlib_intsort();//快速排序一个整型实例


getchar();
getchar();
return 0 ;
}


//把结构体数据源传递给另一个结构体指针,需要对其每一个元素进行逐一复制(重点在于对结构体元素的操作)
void copy_student(my_student_data * src, my_student_data * det)
{
det->stu_num = src->stu_num ;
det->stu_score = src->stu_score;
det->stu_class =src->stu_class;
strcpy(det->stu_name,src->stu_name);
}


//排序算法,传递两个结构体指针,根据需求对其元素进行复合排序
bool compare(my_student_data * s1, my_student_data * s2)
{
if (s1->stu_num != s2->stu_num)
{
/*如果需要比较的两个结构体元素不相等,那么就返回一个bool值,
判断是否应当进行位置调换,否则相等,对其进行下一个关键字的判断。*/
return s1->stu_num < s2->stu_num;
}
if (s1->stu_score != s2->stu_score)
{
return s1->stu_score >s2->stu_score;
}
if (s1->stu_class != s2->stu_class)
{
return s1->stu_class < s2->stu_class ;
}
return false;
}


void stu_sort()
{
int i = 0 ,j = 0;
int k = j;
my_student_data t ;


for (i = 0 ;i < str_size ;i++)  
//对于n个数据,应当进行n-1次排序,每一轮排序既可以确定一个数据的位置(外循环排序)
{
for( j = i+1 ;j < str_size;j++) 
//对于每一轮的排序,只需从当前第 i 个数据,跟(i+1)及以后的每一个数据进行比较,找出本轮的最值
{
//if(a[ j+1] > a[ j ]) 此算法错误在于,每轮只能与相邻的两个数据进行比较,
if(!compare(&stu[i], &stu[j]))
//传递两个结构体指针,按需求对其元素进行比较,确定排序规则
{
//t = stu[j];  算法错误
//stu[j]=stu[j+1];
//stu[j+1]=t;
copy_student(&stu[i],&t);//当需要交换两个结构体的位置的时候,复制其各个元素信息
copy_student(&stu[j],&stu[i]);
copy_student(&t,&stu[j]);
}


}
}
for (i=0;i<str_size;i++)
{
put_student_int(i);
}


}


void int_sort()
{
int a[9] = {4, -43, 43, 54, 20, 94, 13, 15, 17};
int i = 0 ,j = 0;
int t = 0 ;


for (i = 0 ;i < 9 ;i++)
{
for( j = i+1 ;j < 9;j++)
// j = i+1表示当前第 i 将于其后每个元素进行比较,找出本轮的最值,进行交换
{
//if(a[j] > a[ j+1]) 错误算法,每次只能与相邻的两个元素进行比较,
//{
// t = a[j];
// a[j]=a[j+1];
// a[j+1]=t;
//}
if (a[i] > a[j])
{
t = a[i];
a[i]=a[j];
a[j]=t;
}
}
}


for (i =0 ;i<9;i++)
{
printf(" %d ",a[i]);
}
}


int num_to_index(int s_num)
{
int index = 0;
int i =0 ;
for( i =0 ;i<str_size;i++)
{
if (s_num == stu[i].stu_num )
{
return i ;//把学号转换为索引值
}
}
return 0;
}


void put_student_int(int i)
{
//printf("stu_num = %d , stu_score = %d , stu_class = %d , stu_name= %s \n",
// stu[i].stu_num,stu[i].stu_score,stu[i].stu_class,stu[i].stu_name);//改写成一个输出函数


put_student(&stu[i]);

}


void put_student(Student_date* stu)
{
printf("stu_num = %d , stu_score = %d , stu_class = %d , stu_name= %s \n",
stu->stu_num,stu->stu_score,stu->stu_class,stu->stu_name);
}




//二,外部方案排序
//--------------------------外部排序-----------------------------


//(一)索引排序:


bool index_compare(int *left, int *right)
{
return compare(&stu[*left] ,&stu[*right]);
}


void index_sort()   //索引排序法 (间接排序,即不改变数据源信息)
{
//索引排序
int i=0, j=0;
int t =0;
int *index = (int*)malloc(str_size*sizeof(int)); //给索引值分配内存空间
if (index == NULL)  
/*(细节重点)一旦对指针分配内存空间,就要对其进行判断是否成功分配,
并且用完后需要对其释放*/
{
return;
}


//初始化索引值
for (i=0; i<str_size; ++i)
{
(*(index+i)) = i;  
/* 把索引值传递给(*(index+i)),其中index为整形指针,(index+i)引用各内存空间,
(*(index+i)) 访问其内容。*/
}


//对索引进行排序
for (i = 0 ;i < str_size ;i++)
{
for( j = i+1 ;j < str_size;j++)
{
//if(a[ j+1] > a[ j ])
if(!(index_compare(&index[i], &index[j])))
///*调用index_compare函数,用引用把索引地址值传递给结构体变量stu[]的下标,
//再引用结构体的变量的地址,按算法排序*/
{
t = index[i];
index[i]=index[j];
index[j]=t;
        //注意:此方法并为外部引用,通过借助中间变量索引值index,来改变索引值的顺序
//从而改变输出顺序,来达到排序的效果
//copy_student(&index[j],&t);
//copy_student(&index[j+1],&index[j]);
//copy_student(&t,&index[j+1]);
}


}
}

//排序前的结果
for (i=0; i<str_size; ++i)
{
put_student_int(i);     //未改变顺序前的索引值;
}


printf("\n");
printf("--------------------------------------\n");
//输出索引排序结果
for (i=0; i<str_size; ++i)
{
put_student_int(index[i]);
//改变索引顺序后的输出
}


free(index);
}










//(二)指针排序法
bool compare_ptr(my_student_data **left, my_student_data **right)
{
return compare(*left, *right);//传递一维结构体指针变量,调用compare()函数排序算法进行排序
}


void swap_ptr(my_student_data **left, my_student_data **right)
{
my_student_data* t = NULL;
t = *left;
*left = *right;
*right = t;
}


//通过指针来排序
void ptr_sort()
{
//通过指针来进行索引排序
my_student_data **ptrArray = 
(my_student_data**) malloc(str_size * sizeof(my_student_data*));
//对于二维结构体指针变量 ptrArray 中每个元素类型为 一维结构体指针 
if (ptrArray == NULL)  
{
return;
}


int i=0, j=0;
my_student_data *t = NULL;


//初始化指针
for (i=0; i<str_size; ++i)
{
ptrArray[i] = &stu[i];//把源数据信息传递给二维结构体指针,
}


//排序
for (i = 0 ;i < str_size ;i++)
{
for( j = i+1 ;j < str_size;j++)
{
//if(a[ j+1] > a[ j ])
if(!compare_ptr(&ptrArray[i], &ptrArray[j]))//对引用一维结构体指针元素的地址进行排序,
{
//t = index[i];
//index[i]=index[j];
//index[j]=t;


//copy_student(&index[j],&t);
//copy_student(&index[j+1],&index[j]);
//copy_student(&t,&index[j+1]);


swap_ptr(&ptrArray[i], &ptrArray[j]);  //交换一维结构体指针的位置
}
}
}


printf("按照指针排序的结果:\n");
//排序前的结果
for (i=0; i<str_size; ++i)
{
put_student_int(i);
}


printf("\n");
printf("--------------------------------------\n");
//输出索引排序结果
for (i=0; i<str_size; ++i)
{
put_student(ptrArray[i]);
}


free(ptrArray);
}




//(三)调用库函数的qsort()快速排序函数实现排序
int compare_qsort(const void* left, const void* right)
{
int ret = 0;
Student_date* l = (Student_date*)left;
Student_date* r = (Student_date*)right;


if(true == compare(l, r))
{
return -1;
}


return 1;
}


void qsort_stdlib()
{
int i=0;
printf("按照排序函数排序的结果:\n");
//排序前的结果
for (i=0; i<str_size; ++i)
{
put_student_int(i);
}


qsort(stu, str_size, sizeof(Student_date), compare_qsort);


//快速排序函数及其原型解析:
/*_CRTIMP void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void * _Base, 
_In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, 
_In_ int (__cdecl * _PtFuncCompare)(const void *, const void *));*/
/*排序函数解析qsort(stu(需要排序的数据源首地址), str_size(数据源的大小,即结构体元素个数), 
sizeof(Student_date)(数据源类型的大小,即数据源元素结构体所占用的字节), 
compare_qsort(排序方案));*/


printf("\n");
printf("--------------------------------------\n");
//输出索引排序结果
for (i=0; i<str_size; ++i)
{
put_student_int(i);
}
}


void qsort_stdlib_intsort()
{
int a[9] = {4, -43, 43, 54, 20, 94, 13, 15, 17};
//qsort排序
int i = 0 ;
qsort(a, 9, sizeof(int), compare_qsort_num);//调用快速排序函数
for (i=0; i<9; ++i)
{
printf(" %d " ,a[i]);
}
}


int compare_qsort_num(const void* left, const void* right) //对a【9】数组的排序算法
//(const void* left, const void* right)调用的是原函数的参数类型
{
int ret = 0;
int* l = (int*)left;  //把原函数的参数类型强制转化为 int* 型。
int* r = (int*)right;


//if(true == compare_num(l, r))
//{
// return -1;
//}


//return 1;


if (*l != *r) //如果左右两边的数不想等
{
if(*l < *r)  //左边数小于右边数
return -1;
else
return 1;  //左边数大于右边数
}


return 0;  //如果左右两边的数值相等

}


三、快速排序原理(分治法):http://blog.csdn.net/morewindows/article/details/6684558


#include "stdio.h"
void quick_sort(int s[], int l, int r) ;
int  main()
{
int s[10]={23,12,73,24,9,78,45,56,30,10};
int l=0,r=9;
//quick_sort(s,l,r);
//Swap(a[0],a[9]);

for (int i=0;i<10;i++)
{
printf(" %d ",s[i]);
}


getchar();
getchar();
return 0;
}


void quick_sort(int s[], int l, int r)  
{  
if (l < r)  
{  
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1  
int i = l, j = r, x = s[l];  
while (i < j)  
{  
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数  
j--;    
if(i < j)   
s[i++] = s[j];  


while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数  
i++;    
if(i < j)   
s[j--] = s[i];  
}  
s[i] = x;  
quick_sort(s, l, i - 1); // 递归调用   
quick_sort(s, i + 1, r);  
}  
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值