1. 程式人生 > >面試題22——編碼實現堆排,歸併排序,基數排序

面試題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 表示當前數字從右往左數的位數
	}
}