内排序-数组实现(c++)

参考资料:数据结构与算法分析(第三版)(c++)
          http://blog.csdn.net/theprinceofelf/article/details/6672677
		  
		  
		  
		  
    内排序,均采用数组实现,数组有较多的局限性,这些实现是为了去了解排序算法
的操作流程

#include<iostream>
using namespace std;

void Swap(int &a,int &b);
void Print(int *array,int n);
void BubbleSort(int *array,int n); 
void InsertSort(int *array,int n); 
void ShellSort(int *array,int n);
void RadixSort(int *array,int n,int k,int r,int *cnt,int *B);
void QuickSort(int Left,int Right,int *array); 
int FindPos(int Left,int Right);
int Parttion(int Left,int Right,int& pos,int *A);
void MergeSort(int Left,int Right,int *array,int *B);
void ShellSort(int *array,int n);
void IssSort(int *array,int n,int temp);
void HeapSort(int *array,int n);
void HeapAdjust(int *array,int high,int low);
int main()
{
	int n=20;
	int arry[n]={12,45,78,2,3,45,12,47,36,5,112,1178,14,20,10,58,74,65,24,17};
	//这两个数组主要是在用数组实现基数排序过程中要使用到 
	int cnt[n];
	int B[n];
	
	printf("要进行排序的数组为:\n");
	Print(arry,n);
	
	
 	printf("冒泡排序:\n");
	BubbleSort(arry,n);
	Print(arry,n);
	printf("插入排序:\n");
	InsertSort(arry,n);
	Print(arry,n);
	printf("基数排序:\n");
	RadixSort(arry,n,4,10,cnt,B);
	Print(arry,n);
	printf("快速排序:\n");
	QuickSort(0,n-1,arry);
	Print(arry,n);
	printf("归并排序:\n");
	MergeSort(0,n-1,arry,B);
	Print(arry,n);
	printf("希尔排序:\n");
	ShellSort(arry,n);
	Print(arry,n);
	printf("堆排序:\n");
	HeapSort(arry,n);
	Print(arry,n);
	return 0;
}



void Swap(int &a,int &b)
{
	int temp=a;
	a=b;
	b=temp;
}

void Print(int *array,int n)
{
	
	for(int i=0;i<n;i++)
	{
		printf("%d\t",array[i]);
	}
	printf("\n\n");
}

//冒泡排序的时间复杂度为n^2,稳定 
void BubbleSort(int *array,int n)
{
	for(int i=0;i<n;i++)
	{
		//for(int j=n-i;j>0;j--)  //这个是从最后一位开始进行冒泡排序,比较直观 
		for(int j=0;j<n-1-i;j++)
		{
			if(array[j]>array[j+1])
			{
				Swap(array[j],array[j+1]);
			}
		}
	}
}
 
//插入排序的实现 
void InsertSort(int *array,int n)
{
	for(int i=1;i<n;i++)
	{
		for(int j=i;j>0;j--)
		{
			if(array[j]<array[j-1])
			{
				Swap(array[j],array[j-1]);
			}
		}
	}
}


 
//基数排序的数组实现的过程
 /*参数的意义:三个数组为交换过程中的使用,标记位置过程的使用,原数组
 K为要进行排序的数组中数字的最大位数,r为进制*/ 
void RadixSort(int *array,int n,int k,int r,int *cnt,int *B)
{
	int j;
    
	for(int i=0,rtoi=1;i<k;i++,rtoi*=r)
	{
		for(j=0;j<r;j++)
		{
			cnt[j]=0;
		}
		for(j=0;j<n;j++)
		{
			cnt[(array[j]/rtoi)%r]++;
		}
		for(j=1;j<r;j++)
		{
			cnt[j]=cnt[j]+cnt[j-1];
		}
		for(j=n-1;j>=0;j--)
		{
			//式子中所要表达的就是进行取余,从最低位开始进行 
			B[--cnt[(array[j]/rtoi)%r]]=array[j];
		}
		for(j=0;j<n;j++)
		{
			array[j]=B[j];
		}
	}
}



//快速排序实现,选择轴值在中间,但是在极端情况下,轴值在首位或者末尾均可
//快速排序的优化有许多的方式,可以用堆栈代替递归,子数组在排序时长度的选择均可以进行优化 
void QuickSort(int Left,int Right,int *A)
{
   if (Left >= Right)
	{
		return;
	}
	//将轴值放在数组的最后
	int pos = FindPos(Left, Right);
	Swap(pos, Right);
	// Left-1这个位置在数组的下界之前,目的是为了防止溢出
	int k = Parttion(Left - 1, Right, A[Right],A);
	Swap(k, Right);
	QuickSort(Left, k - 1,A);
	QuickSort(k + 1, Right,A);
}


int FindPos(int Left, int Right)
{
	return (Left + Right) /2;
}


int Parttion(int Left, int Right, int& pos,int *A)
{
	int i = Left;
	int j = Right;
	do
	{
		while ((pos>=A[Left])&&(Left<Right))
		{
			Left++;
		}
		//此处Left<Right保证了当轴值为子数组的最小值(即分隔出来以后左半部分的长度为0)不会越界
		while ((Left < Right) && (pos <=A[Right]))
		{
			Right--;
		}
		Swap(Left, Right);
	} while (Left < Right);
	return Left;
}



//归并排序的实现:  
void MergeSort(int Left,int Right,int *array,int *B)
{
	if(Left==Right)
	{
		return;
	}
	int mid=(Left+Right)/2;
	MergeSort(Left,mid,array,B);
	MergeSort(mid+1,Right,array,B);
	//复制到数组B中进行操作 
	for(int i=Left;i<=Right;i++)
	{
		B[i]=array[i];
	}
	
	int i=Left,j=mid+1;
	for(int k=Left;k<=Right;k++)
	{
		//左侧数组是否已经用完 
		if(i==mid+1)
		{
			array[k]=B[j++];
		}
		//右侧数据是否用完 
		else if(j>Right)
		{
			array[k]=B[i++];
		}
		//均未用完,则需要进行比较归位 
		else if(B[i]<B[j])
		{
			array[k]=B[i++];
		}
		else
		{
			array[k]=B[j++];
		}
	}
}


//希尔排序的实现
//希尔排序的最后一轮处理其实就是插入排序 
void ShellSort(int *array,int n)
{
	for(int i=n/2;i>2;i/=2)
	{
		for(int j=0;j<i;j++)
		{
			IssSort(&array[j],n-j,i);
		}
		//最后一次处理为插入排序。所以增量为1 
		IssSort(array,n,1);
	}
}



void IssSort(int *array,int n,int temp)
{
	for(int i=temp;i<n;i+=temp)
	{
		for(int j=i;(j>=temp)&&(array[j]<array[j-temp]);j-=temp)
		{
			Swap(array[j],array[j-temp]);
		}
	}
}




//堆排序的实现
void HeapSort(int *array,int n)
{
	for(int i=n/2-1;i>=0;--i)
	{
		HeapAdjust(array,i,n-1);
	}
	for(int i=n-1;i>0;--i)
	{
		Swap(array[0],array[i]);
		HeapAdjust(array,0,i-1);
	}
}



void HeapAdjust(int *array,int low,int high)
{
	int temp=array[low];
	for(int i=low*2+1;i<=high;i*=2)
	{
		if(i<high&&array[i]<=array[i+1])
		{
			++i;
		}
		if(array[i]<=temp)
		{
			break;
		}
		array[low]=array[i];
		low=i;
	}
	array[low]=temp;
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个示例代码,演示如何使用C语言对结构体数组进行排序。假设我们有一个结构体定义如下: ```c typedef struct { int id; char name[20]; float score; } Student; ``` 我们可以使用qsort函数对结构体数组进行排序,该函数使用快速排序算法。在调用qsort函数时,我们需要提供以下参数: - 基础数组的起始地址 - 数组中元素的数量 - 每个元素的大小 - 一个指向比较函数的指针 比较函数用于比较两个元素的大小,如果第一个元素应该排在第二个元素之前,则返回负数;如果第一个元素应该排在第二个元素之后,则返回正数;如果两个元素相等,则返回0。 以下是一个使用qsort函数对结构体数组进行按分数从高到低排序的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int id; char name[20]; float score; } Student; int compare(const void* a, const void* b) { const Student* s1 = (const Student*)a; const Student* s2 = (const Student*)b; if (s1->score < s2->score) { return 1; } else if (s1->score > s2->score) { return -1; } else { return 0; } } int main() { Student students[] = { {1, "Alice", 85}, {2, "Bob", 92}, {3, "Charlie", 76}, {4, "David", 89}, {5, "Eva", 94}, }; int num_students = sizeof(students) / sizeof(Student); qsort(students, num_students, sizeof(Student), compare); for (int i = 0; i < num_students; i++) { printf("%d\t%s\t%.1f\n", students[i].id, students[i].name, students[i].score); } return 0; } ``` 在此示例代码中,我们首先定义了一个包含5个学生的结构体数组。我们计算数组中元素的数量,并将其传递给qsort函数。然后,我们传递每个元素的大小和compare函数的指针。 compare函数根据学生的分数比较两个学生的大小。我们首先将void指针强制转换为指向Student结构体的指针,然后使用指针访问结构体的score字段。如果第一个学生的分数小于第二个学生的分数,则返回1,表示第一个学生应该排在第二个学生之后。如果第一个学生的分数大于第二个学生的分数,则返回-1,表示第一个学生应该排在第二个学生之前。如果两个学生的分数相等,则返回0。 最后,我们使用for循环遍历已排序数组,并使用printf函数打印每个学生的信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值