实验目的与实验要求
一、实验目的
1. 掌握常用的排序方法,并掌握用高级语言实现排序算法的方法;
2. 深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;
3. 了解各种方法的排序过程及其时间复杂度的分析方法。
二、实验要求
统计成绩:给出n个学生的考试成绩表,每条信息由姓名和分数组成,试设计一个算法:
(1) 按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次;
(2) 按名次列出每个学生的姓名与分数。
实验任务
认真阅读与理解实验内容的具体要求,参考教材相关章节,编写实验程序并上机调试与测试,完成实验报告的撰写。
习题集8:查找算法的实现
1、实现思路
尽管之前手撕过快速排序 但不得不说快速排序确实细节很多 在写了这么多次 现在立马写 还是有很多小问题 还是去看了看自己之前写的才写出来
作为最后一个实验 那也就画上句号了 也不说多的了 下午还有其他东西要做 下面就直接给代码吧
2、代码实现(快排+插入)
#include <stdio.h>
#include <string.h>
typedef struct
{
char name[8];
int score;
} student;
void swap(student* stu1,student* stu2)
{
student tmp;
tmp = *stu2;
*stu2 = *stu1;
*stu1 = tmp;
}
int insert_sort(student* stu,int lo,int hi)
{
int i,j;
student tmp;
for(i=lo+1;i<=hi;++i)
{
tmp = *(stu+i);
int score = tmp.score;
for(j=i;j>lo && score > stu[j-1].score;--j)
stu[j] = stu[j-1];
stu[j] = tmp;
}
}
int partition(student* stu,int lo,int hi)
{
int i = lo,j = hi+1,lo_score = stu[lo].score;
while(i < j)
{
++i;--j;
while(i<hi && stu[i].score >= lo_score) ++i;
while(j>lo && stu[j].score <= lo_score) --j;
if(i < j) swap(stu+i,stu+j);
}
swap(stu+lo,stu+j);
return j;
}
void quick_sort(student* stu,int left,int right)
{
if(left >= right) return;
int pos = partition(stu,left,right);
quick_sort(stu,left,pos-1);
quick_sort(stu,pos+1,right);
}
int main()
{
int i,students,score;
char tmp[8];
printf("the num of students to be sort:");
scanf("%d",&students);
student stu[100];
printf("the info of stu like,100 Tom\nName Score:\n");
for(i=0;i<students;++i)
{
memset(tmp,0,sizeof(tmp));
scanf("%d %s",&score,tmp);
stu[i].score = score;
strcpy(stu[i].name,tmp);
}
quick_sort(stu,0,students-1);
//insert_sort(stu,0,students-1);
int pos = 0,sumpos = 1,prescore = -1;
for(i=0;i<students;++i)
{
if(prescore == stu[i].score) ++sumpos;
else
{
pos += sumpos;
sumpos = 1;
}
printf("top:%d,name:%s,score:%d\n",pos,stu[i].name,stu[i].score);
if(i) prescore = stu[i].score;
}
return 0;
}
/*14
70 Bill
69 Jimmy
75 Sam
75 Nika
80 Momo
30 Poki
95 Nuke
80 Jake
90 Mary
99 Jannie
59 Molly
30 Toka
9 Bob
100 Tom
*/
3、实现效果
补充(快排非递归 + 归并递归)
最近 快排手撕起来 非递归 递归版
还有归并算法 现在如同案板上的鱼肉一样了
下面就放一个 c++
版本的非递归快排 + 归并递归吧
都是2-3分钟写出来的
1、快排非递归版本
int partition(vector<int>& nums,int lo,int hi)
{
int i = lo,j = hi + 1;
while(i < j)
{
while(i < hi && nums[++i] <= nums[lo]);
while(j > lo && nums[--j] >= nums[lo]);
if(i < j) swap(nums[i],nums[j]);
}
swap(nums[lo],nums[j]);
return j;
}
void push_stack(stack<int>& stack,int num1,int num2)
{
if(num1 >= num2) return;
stack.push(num1);
stack.push(num2);
}
vector<int> sortArray(vector<int>& nums) {
stack<int> stack;
push_stack(stack,0,nums.size()-1);
while(!stack.empty())
{
int hi = stack.top();stack.pop();
int lo = stack.top();stack.pop();
int mid = partition(nums,lo,hi);
push_stack(stack,lo,mid-1);
push_stack(stack,mid+1,hi);
}
return nums;
}
2、归并递归版
void merge(vector<int>& nums,vector<int>& tmp,int lo,int hi)
{
int mid = (lo + (hi - lo)/2);
int l = lo,r = mid+1,ptr = lo;
while(l <= mid && r <= hi)
{
if(nums[l] <= nums[r]) tmp[ptr++] = nums[l++];
else tmp[ptr++] = nums[r++];
}
while(l <= mid) tmp[ptr++] = nums[l++];
while(r <= hi) tmp[ptr++] = nums[r++];
for(int i = lo;i <= hi;++i)
nums[i] = tmp[i];
}
void merge_sort(vector<int>& nums,vector<int>& tmp,int l,int r)
{
if(l >= r) return;
int mid = (l+r)/2;
merge_sort(nums,tmp,l,mid);
merge_sort(nums,tmp,mid+1,r);
merge(nums,tmp,l,r);
}
vector<int> sortArray(vector<int>& nums) {
vector<int> tmp(nums.size(),0);
merge_sort(nums,tmp,0,nums.size()-1);
return tmp;
}