1. 程式人生 > >資料結構(一) 交換排序

資料結構(一) 交換排序

最近只看了冒泡和快排這兩個演算法,今天面試就讓寫排序,用電腦寫,一去就讓寫程式碼,賊慌,然後面試官小姐姐真的賊好看,就是和麵試官小哥談論我的簡歷,坐在我對面,看著我寫程式碼真的賊慌。。

一開始本來想寫快排,因為緊張,大腦短路,滿腦子都在冒泡泡。。最後還是寫了冒泡,,這裡再回顧一下冒泡和快排吧,鞏固一下,免得一緊張就慌的寫不出來。

(一)冒泡泡排序法

總的思想就是從待排序表的底部,通過兩兩交換的將較小的元素交換到排序表上層。

注意兩點:

1、已經排過序的較小的元素不參與之後的排序,即巢狀的迴圈裡面,從表尾一直迴圈到已經排序好的元素位置。

2、當剩餘的元素已經有序時,不需要再執行剩下的迴圈判斷工作,主要通過新增標記變數來判斷是否有進行交換。

帶排序的順序表結構和swap函式如下:

typedef struct{
	int a[100];
	int len;
}SqList;
void swap(SqList *L, int i, int j)
{
	int temp;
	temp = L->a[i];
	L->a[i] = L->a[j];
	L->a[j] = temp;
}

冒泡實現(親測有效)

void BubbleSort(SqList *list)
{
	bool flag = true;//第二個注意點
	for (int i = 0; i < list->len&&flag; i++)
	{
		flag = false;
		for (int j = list->len - 2; j >= i; j--)//第一個注意點
		{
			if (list->a[j] > list->a[j + 1])
			{
				swap(list, j, j + 1);
				flag = true;
			}

		}
	}
}

(二)快速排序(20世紀十大演算法之一,聽起來好厲害)

是基於分治法的交換排序。根據某個基準數值(通常是第一個),將表分成兩部分,使得小於這個基準數的數都在基準數的左邊,大於這個基準數的數都在基準數的右邊。再分別對這兩邊進行同樣的操作。需要用到遞迴的思想。

實現如下,程式碼量很少,重點在Partition()函式的實現上。

void QuickSort(SqList *list, int low, int high)
{
	if (low < high)
	{
		int piovtpos = Partition(list, low, high);
		QuickSort(list, low, piovtpos - 1);
		QuickSort(list, piovtpos + 1,high);
	}
}

需要儲存當前待排元素的基準值pivot;指向表頭的指標low,用下標表示(為了找到比pivot大的值);指向表尾的指標為high,用下標表示(為了找到比pivot小的值)。

再來琢磨一下這個Partition()方法,分治的方法有好幾種,我就主要理解了以前課本上學的從兩端開始查詢,先找到比pivot小的(一定要先移動high指標),再找到比pivot小的,交換他們的位置,直到兩個指標相遇,用pivot替換這兩個指標相遇的位置,就把表分成了兩個部分。主要要對比的就是pivot、a[low]、a[high]。把這三個數的順序排好,填到相應的位置。先找到最小的,放在最左端,再找到最大的放到最右端,中間就放pivot。實現了整個交換的過程。

int Partition(SqList *list, int low, int high)
{
	int pivot = list->a[low];
	while (low < high)
	{
		while (low < high&&list->a[high] >= pivot)
		{
			--high;
		}
		list->a[low] = list->a[high];//從表的尾巴開始找到了比pivot小的,放到pivot左端
		while (low < high&&list->a[low] <= pivot)
		{
			++low;
		}
		list->a[high] = list->a[low];//從表的尾頭開始找到了比pivot大的,放在pivot右端
	}
	list->a[low] = pivot;//在兩個指標的相遇位置放下pivot使得左邊的元素都小於pivot右邊的都大於piovt
	return low;
}

測試用例:

int _tmain(int argc, _TCHAR* argv[])
{
	SqList list;
	int data[] = { 9, 10, 5, 6, 7, 8,1,2 };
	int len = sizeof(data) / sizeof(int);
	for (int i = 0; i < len; i++)
	{
		list.a[i] = data[i];
	}
	list.len = len;
	//cout << len << endl;
	//BubbleSort(&list);
	QuickSort(&list,0,len-1);
	for (int i = 0; i < list.len; i++)
	{
		cout << list.a[i] <<" ";
	}

	return 0;
}