面试题22——编码实现堆排,归并排序,基数排序

堆排(大根堆):

void adjust(int*arr,int start,int end)
{
	int tmp=arr[start];
	for(int i=2*start+1;i<=end;i=2*i+1)
	{
		if(i<end&&arr[i]<arr[i+1])
		{
			i++;
		}
		if(arr[i]>tmp)
		{
			arr[start]=arr[i];
			start=i;
		}
		else
		{
			break;
		}
	}
	arr[start]=tmp;
}
void headpsort(int*arr,int len)
{
	for(int i=(len-1-1)/2;i>=0;i--)
	{
		adjust(arr,i,len-1);
	}
	int tmp=0;
	for(int i=0;i<len-1;++i)
	{
		tmp=arr[0];
		arr[0]=arr[len-1-i];
		arr[len-1-i]=tmp;
		adjust(arr,0,len-1-i-1);
	}
}

归并排序:

void Merge(int *arr,int len,int gap)
{
	int*brr=(int*)malloc(sizeof(int)*len);
	assert(brr!=NULL);
	int i=0;
	//判断 start1,end1,start2,end2 的位置
	int s1=0;
	int e1=s1+gap-1;
	int s2=e1+1;
	int e2=s2+gap-1<len-1?s2+gap-1:len-1;
	//当有两个归并段时
	while(s2<len)
	{
	//两个归并段都有数据
		while((s1<=e1)&&(s2<=e2))
		{
			if(arr[s1]<=arr[s2])
			{
				brr[i++]=arr[s1++];
			}
			else
			{
				brr[i++]=arr[s2++];
			}
		}
		//退出循环的两种方式
		while(s1<=e1)
		{
			brr[i++]=arr[s1++];
		}
		while(s2<=e2)
		{
			brr[i++]=arr[s2++];
		}
		s1=e2+1;
		e1=s1+gap-1;
		s2=e1+1;
		e2=s2+gap-1<len-1?s2+gap-1:len-1;
	}
	//只有一个归并段时
	while(s1<len)
	{
		brr[i++]=arr[s1++];
	}
	for(int i=0;i<len;++i)
	{
		arr[i]=brr[i];
	}
	free(brr);
	brr=NULL;
}
void Mergesort(int*arr,int len)
{
	for(int i=1;i<len;i*=2)
	{
		Merge(arr,len,i);
	}
}

基数排序:

//每个桶内存储数据时相当于进行单链表的操作,创建单链表
typedef struct Node
{
	int data;
	struct Node*next;
}Node,*List;
//单链表的初始化
void InitList(List plist)
{
	assert(plist!=NULL);
	plist->next=NULL;
}
//新建一个结点
static Node*GetNode(int val)
{
	Node*pGet=(Node*)malloc(sizeof(Node));
	assert(pGet!=NULL);
	pGet->data=val;
	pGet->next=NULL;
	return pGet;
}
//单链表的尾插,入桶
bool Insert(List plist,int val)
{
	Node*p=plist;
	while(plist->next!=NULL)
	{
		p=p->next;
	}
	Node*pGet=(Node*)malloc(sizeof(Node));
	p-<next=pGet;
	return true;
}
//删除并保存值,出桶操作
bool DelFirst(List plist,int*rtv)
{
	Node*p=plist->next;
	if(p==NULL)
	{
		return false;
	}
	*rtv=p->data;
	plist->next=p->next;
	free(p);
	p=NULL;
	return true;
}
//找出最大数并确定最大数的位数
int GetBitMax(int*arr,int len)
{
	int max=arr[0];
	int count=0;
	for(int i=1;i<len;++i)
	{
		if(arr[i]>max)
		{
			max=arr[i];
		}
	}
	while(max!=0)
	{
		count++;
		max/=10;
	}
	return count;
}
//得到figure位上的数值
int Getnum(int num,int figure)
{
	for(int j=0;j<figure;++j)
	{
		num=num/10;
	}
	return num%10;
}

void Base(int*arr,int len,int figure)
{
	assert(arr!=NULL);
	//创建桶
	Node head[10];
	for(int i=0;i<10;++i)
	{
		InitList(&head[i]);
	}
	int tmp;
	for(int j=0;j<len;j++)
	{
		tmp=Getnum(arr[j],figure);
		//得到 j 号下标 figure 位的数值
		Insert(&head[tmp],arr[j]);
		//入桶,遍历数组 figure 位相应的数据进入相应的桶里
	}
	int n=0;
	for(int j=0;j<10;)
	{
		if(DelFirst(&head[j],&arr[n]))
		{
			n++;
//j 号桶不一定只有一个数据,遍历整个数组用 n 代表一个桶里存放数据的下表,
//避免出现多个数据使数据存放出现问题,覆盖掉原先值或赋值后不改变
		}
		else
		{
			j++;
		}
	}
}
void Basesort(int*arr,int len)
{
	int count=GetBitMax(arr,len);
	for(int i=0;i<count;++i)
	{
		Base(arr,len,i);//i 表示当前数字从右往左数的位数
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42323413/article/details/84898591