基數排序

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

/*
十位 0~9   低位優先  鏈式隊列 (若順序,則浪費空間大,某一時刻有可能全進一個隊列)
先放個位  後出隊
第一遍後 個位從小到大有序 
第二遍後 十位從小到大有序
*/

typedef struct Node
{
	int data;
	struct Node *next;
}Node;

typedef struct HNode//隊列的類型
{
	struct Node *front;
	struct Node *rear;
}HNode,*PQueue;

Node *BuyNode(int val)
{
	Node *p = (Node *)malloc(sizeof(Node));
	assert(p != NULL);
	p->data = val;
	p->next = NULL;
	return p;
}

void InitQueue(PQueue pq)//初始化
{
	assert(pq != NULL);
	pq->front = NULL;
	pq->rear = NULL;

}


void Push(PQueue pq, int val)//入隊
{
	Node *p = BuyNode(val);

	/*if (pq->front == NULL)//第一次插  需要注意
	{ 
		pq->front = p;
		pq->rear = p;
	}
	pq->rear->next = p;
	pq->rear = p;*/  // pq的尾指針需要指向隊尾
	if (pq->front == NULL)//第一次插  需要注意
	{
		pq->front = p;
	}
	else 
	{ 
		pq->rear->next = p;
	}
	pq->rear = p; 

}


//獲取隊頭的值
bool Pop(PQueue pq, int *rtval)
{
	if (pq->rear == NULL)//隊頭隊尾效果一樣
	{
		return false;
	}

	Node *p = pq->front;
	*rtval = p->data;

	pq->front = p->next;
	free(p);

	if (pq->front == NULL)//防止最後一個爲野指針
	{
		pq->rear = NULL;
	}
	return true;
}

//得到十進制數字num右數第figure位的值
//例如 (123,0)
int GetFigure(int num, int figure)
{
	for (int i = 0; i < figure; i++)
	{
		num /= 10;
	}
	return num % 10;
}

//figure 從0開始 
void Radix(int *arr, int len, int figure)//figure 右數第幾位 作爲關鍵字
{
	HNode head[10];
	int i ,key;
	for (i = 0; i < 10; i++)
	{
		InitQueue(&head[i]);//O(n)
	}

	for (i = 0; i < len; i++)//進
	{
		key = GetFigure(arr[i], figure);//例如 key=(123,0)=3
		Push(&head[key], arr[i]);
	}

	int j = 0;//桶號
	for (i = 0; i < len;)//出
	{
		if (Pop(&head[j], &arr[i]))//j號桶內有數字
		{
			i++;
		}
		else//出失敗 說明當前沒數據
		{
			j++;
		}
	}

}

int GetMaxFigure(int *arr, int len)//判斷最大值的位數  比較的趟數
{
	int max = arr[0];
	int count = 0;
	for (int i = 0; i < len; i++)
	{
		if (max < arr[i])
		{
			max = arr[i];
		}
	}

	do //杜絕0的判斷
	{
		count++;
		max /= 10;
	} while (max != 0);

	return count;
}

void RadixSort(int *arr, int len)
{
	int count = GetMaxFigure(arr, len);
	for (int i = 0; i < count; i++)
	{
		Radix(arr,len,i);
	}
}

void Show(int *arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 4,9,6,8,5,7 };
	int len = sizeof(arr) / sizeof(arr[0]);
	RadixSort(arr, len);
	Show(arr, len);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章