冒泡排序&快速排序

     冒泡排序和快速排序都是一类借助交换进行排序的方法,快速排序是比较简单的一种。
     冒泡排序首先将第一个记录的关键字和第二个记录的关键字进行比较,如果第一个记录的关键字大于第二个记录的关键字则将这两个记录的位置进行交换。然后比较第二个记录的关键字和第三个记录的关键字并进行同样的操作。直到比较完第 n − 1 n-1 n1个记录的关键字和第 n n n个记录的关键字,以上过程称为第一趟冒泡排序,它使得n个记录中关键字最大的记录被放在第n(从1开始计数)个记录的位置上。然后进行第二趟冒泡排序,对前 n − 1 n-1 n1个记录进行同样的操作使得n个记录中关键字第二大的记录被放在第 n − 1 n-1 n1个记录的位置上。整个排序过程需要经过 k ( 1 < = k < n ) k(1<=k<n) k(1<=k<n)冒泡排序。判断冒泡排序结束的条件是一趟冒泡排序的过程中没有发生记录位置的交换。一个冒泡排序的例子见图1(从小到大排序)。

 
图1.

     如果初始序列为正序(即原有序列中记录已经按照关键字从小到大有序),则只需进行一趟冒泡排序,在排序过程中进行 n − 1 n-1 n1次关键字的比较且不需要进行记录位置的互换。如果初始序列为逆序(即原有序列中记录按照关键字从大到小有序),则需要进行 n − 1 n-1 n1趟冒泡排序,需要进行 ∑ i = n 2 ( i − 1 ) = 1 + 2 + 3 + . . . + ( n − 1 ) = n ( n − 1 ) 2 \sum\limits_{i=n}^{2}(i-1)=1+2+3+...+(n-1)=\frac{n(n-1)}{2} i=n2(i1)=1+2+3+...+(n1)=2n(n1)次关键字的比较以及同数量级的记录位置交换。因此总的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

void recordExchange(int &a,int &b)
{
	int temp = a;
	a = b;
	b = temp;
}
void bubbleSort(int record[],int n)
{
	bool recordExchangeStatus = true;
	for (int i = n - 1; (i >= 1) && recordExchange; i--)
	{
		recordExchangeStatus = false;
		for (int j = 0; j < i; j++)
		{
			if (record[j] > record[j + 1])
			{
				recordExchange(record[j],record[j + 1]);
				recordExchangeStatus = true;
			}
		}
	}
}
//测试程序
int main()
{
	int record[7] = {49,38,65,97,76,13,27};
	bubbleSort(record, 7);
	for (int i = 0; i < 7; i++)
	{
		cout << record[i] << endl;
	}
}

     快速排序是对冒泡排序一种改进。它首先任选一个记录(通常是第一个记录,从1开始计数)作为枢轴(或支点,pivot),然后将比该记录关键字小的记录放在该记录的位置之前,将将比该记录关键字大的记录放在该记录的位置之后。这样就以该枢轴为分界线将原序列划分为了两个子序列。这一过程称为一趟快速排序。之后再递归的对两个子序列进行同样的操作直到子序列中的记录的个数小于等于1时为止。
     一趟快速排序的具体做法是,附设两个指针 l o w low low h i g h high high,初始时它们分别指向序列的第一个记录和最后一个记录。算法首先从 h i g h high high指向的位置向前搜索找到第一个关键字小于 p i v o t pivot pivot的关键字的记录并和记录 p i v o t pivot pivot交换位置,然后从从 l o w low low指向的位置向后搜索找到第一个关键字大于 p i v o t pivot pivot的关键字的记录并和记录 p i v o t pivot pivot交换位置,重复这两步直到 l o w = h i g h low=high low=high为止就完成了一趟快速排序。一个快速排序的例子见图2。

 
图2.

     以下代码参考于这里

// A utility function to swap two elements  
void swap(int* a, int* b)
{
	int t = *a;
	*a = *b;
	*b = t;
}

/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition(int arr[], int low, int high)
{
	int pivot = arr[high]; // pivot  
	int i = (low - 1); // Index of smaller element  

	for (int j = low; j <= high - 1; j++)
	{
		// If current element is smaller than the pivot  
		if (arr[j] < pivot)
		{
			i++; // increment index of smaller element  
			swap(&arr[i], &arr[j]);
		}
	}
	swap(&arr[i + 1], &arr[high]);
	return (i + 1);
}
/* This function takes first element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition(int arr[], int low, int high)
{
	int pivot = arr[low]; // pivot  
	int temp= arr[low];
	while (low<high)
	{
		while (low < high&& arr[high]>=pivot)
		{
			high--;
		}
		arr[low] = arr[high];
		while (low < high && arr[low] <= pivot)
		{
			low++;
		}
		arr[high] = arr[low];
	}
	arr[low] = temp;
	return low;
}


/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int arr[], int low, int high)
{
	if (low < high)
	{
		/* pi is partitioning index, arr[p] is now
		at right place */
		int pi = partition(arr, low, high);

		// Separately sort elements before  
		// partition and after partition  
		quickSort(arr, low, pi - 1);
		quickSort(arr, pi + 1, high);
	}
}

/* Function to print an array */
void printArray(int arr[], int size)
{
	int i;
	for (i = 0; i < size; i++)
		cout << arr[i] << " ";
	cout << endl;
}

//测试程序
int main()
{
	int arr[] = { 10, 7, 8, 9, 1, 5 };
	int n = sizeof(arr) / sizeof(arr[0]);
	quickSort(arr, 0, n - 1);
	cout << "Sorted array: \n";
	printArray(arr, n);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值