内部排序算法

news/2024/5/20 0:35:59 标签: 快速排序, 递归, 非递归

快排非递归

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

int partition(int s[], int i, int j)
{
	int value = 0;
	int flag = 1; //判断该从头循环还是尾循环
	value = s[i];
	while(i<j)
	{
		switch(flag)
		{
		case 0:
			if(s[i] < value)
				i++;
			else
			{
				s[j--] = s[i];
				flag = 1;
			}
			break;
		case 1:
			if(s[j] >= value)
				j--;
			else
			{
				s[i++] = s[j];
				flag = 0;
			}
			break;
		}
	}
	s[i] = value;
	return i;
}

void quick_sort(int s[], int l, int r)
{
	int *stack = (int *)malloc(sizeof(int)*(r-l+1));
	int top = 0;
	int index1, index2;
	int res;
	stack[top++] = r;
	stack[top++] = l;
	while(top!=0)
	{
		index1 = stack[--top];
		index2 = stack[--top];
		res = partition(s, index1, index2);

		if(res != index2) //后部分partiton未结束
		{
			stack[top++] = index2;
			stack[top++] = res+1;
		}
		if(res != index1) //前部分partion未结束
		{
			stack[top++] = res-1;
			stack[top++] = index1;
		}
	}
	free(stack);
	stack = NULL;
}

int main()
{
	int number[10] = {8, 1, 8, 4, 9, 5, 8, 10, 3, 6};
	quick_sort(number, 0, 9);
	int i;
	for(i=0; i<10; i++)
	{
		printf("%d, ", number[i]);
	}
	printf("\n");
	return 0;
}



快排递归

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

int partition(int s[], int i, int j)
{
	int value = 0;
	int flag = 1; //判断该从头循环还是尾循环
	value = s[i];
	while(i<j)
	{
		switch(flag)
		{
		case 0:
			if(s[i] < value)
				i++;
			else
			{
				s[j--] = s[i];
				flag = 1;
			}
			break;
		case 1:
			if(s[j] >= value)
				j--;
			else
			{
				s[i++] = s[j];
				flag = 0;
			}
			break;
		}
	}
	s[i] = value;
	return i;
}

void quick_sort(int s[], int l, int r)
{
	int res;
	if(l<r)
	{
		res = partition(s, l, r);
		quick_sort(s, l, res-1);
		quick_sort(s, res+1, r);
	}
}

int main()
{
	int number[10] = {8, 1, 8, 4, 9, 5, 8, 10, 3, 6};
	quick_sort(number, 0, 9);
	int i;
	for(i=0; i<10; i++)
	{
		printf("%d, ", number[i]);
	}
	printf("\n");
	return 0;
}


快排另一种形式:(单链表快排)

详见:http://blog.csdn.net/otuhacker/article/details/10366563

struct LNode {
	int key;
	LNode *next;
	LNode(int key):key(key), next(NULL) {}
};

// 两个指针p、q沿next向后遍历,并保证p之前的元素(除首元素外)比key小, p与q之间的元素(除p所指元素外)比key大
// 最后交换首元素和p所指元素的值
LNode *Partition(LNode *begin, LNode *end) {
	int key = begin->key;
	LNode *p = begin;
	LNode *q = begin->next;
	int temp = 0;
	while (q != end) {
		if (q->key < key) {
			p = p->next;
			temp = p->key;
			p->key = q->key;
			q->key = temp;
		}
		q = q->next;
	}
	temp = begin->key;
	begin->key = p->key;
	p->key = temp;
	return p;
}

// 调用时end赋值为NULL
void QuickSort(LNode *begin, LNode *end) {
	if (begin != end) {
		LNode *partition = Partition(begin, end);
		QuickSort(begin, partition);
		QuickSort(partition->next, end);
	}
}



堆排序

#include <iostream>
#include <vector>

using namespace std;

// 堆排序中, 第i个元素的左孩子的标号为2*i,右孩子的标号为2*i+1
// 连续数组中, 如果i从0开始, 则第i个元素的左孩子的标号为2*i+1, 右孩子的标号为2*i+2

void HeapAdjust(vector<int>& nums, int start, int end) {
	int num = nums[start];
	for (int i = 2 * start + 1; i <= end; i = i * 2 + 1) { // 大顶堆
		if (i < end && nums[i] <= nums[i+1])
			i++;
		if (num >= nums[i])
			break;
		nums[start] = nums[i];
		start = i;
	}
	nums[start] = num;
}

void HeapSort(vector<int>& nums) {
	if (nums.size() <= 1) return;

	// 从最后一个非叶子节点开始堆调整,直到根节点截止
	for (int i = nums.size()/2-1; i >= 0; i--) {
		HeapAdjust(nums, i, nums.size()-1);
	}
	for (int i = nums.size()-1; i > 0; i--) {
		// 将堆顶元素(当前最大元素)与数组第i个元素交换,从而使第i大的元素位置固定
		nums[0] = nums[0] ^ nums[i];
		nums[i] = nums[0] ^ nums[i];
		nums[0] = nums[0] ^ nums[i];

		// 重新调整前i个元素为大顶堆
		HeapAdjust(nums, 0, i-1);
	}
}


int main() {
	vector<int> nums;
	int n;
	int val;
	while (cin >> n) {
		for (size_t i = 0; i < n; i++) {
			cin >> val;
			nums.push_back(val);
		}
		HeapSort(nums);

		for (size_t i = 0; i < nums.size(); i++) {
			cout << nums[i] << " ";
		}
		cout << endl;

		nums.clear();
	}
	return 0;
}





http://www.niftyadmin.cn/n/1437419.html

相关文章

如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器

FFMPEG是一个很好的库&#xff0c;可以用来创建视频应用或者生成特定的工具。FFMPEG几乎为你把所有的繁重工作都做了&#xff0c;比如解码、编码、复用和解复用。这使得多媒体应用程序变得容易编写。它是一个简单的&#xff0c;用C编写的&#xff0c;快速的并且能够解码几乎所有…

字符串模式匹配----KMP算法

1.kmp算法的原理&#xff1a; 本部分内容转自&#xff1a;http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 字符串匹配是计算机的基本任务之一。 举例来说&#xff0c;有一个字符串"BBC ABCDAB ABCDABCDABDE"&#xff0c…

连续子数组的和的最大值、最小值以及和的绝对值的最大值、最小值

#include <iostream> #include <vector> #include <algorithm> using namespace std;//求子数组的最小和 //利用的是dp的思想&#xff0c;依次遍历数组中的每个元素&#xff0c;把他们相加&#xff0c;如果加起来大于0&#xff0c;则 //把当前元素之和清为0&…

阿里c/c++研发工程师实习面试

1. 自我介绍 1&#xff09;自己的简单情况&#xff1a;姓名&#xff0c;年龄&#xff0c;毕业院校&#xff0c;专业&#xff0c;兴趣爱好、性格特点等 2&#xff09;优点与长处&#xff1a;技能、获奖、专业知识、学术背景等 3&#xff09;对应聘职位的想法和规划&…

2015编程之美 彩色的树

题目1 : 彩色的树 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定一棵n个节点的树&#xff0c;节点编号为1, 2, …, n。树中有n - 1条边&#xff0c;任意两个节点间恰好有一条路径。这是一棵彩色的树&#xff0c;每个节点恰好可以染一种颜色。初始时&#xff0c;所…

二叉树几种遍历算法

<span style"font-size:14px;">/*二叉树的遍历*/#include <iostream> #include <cstring> #include <stack> using namespace std;typedef struct node {char data;struct node *lchild,*rchild; }BinTree;typedef struct node1 {BinTree *b…

2015编程之美 2月29日(求闰年的个数)

<span style"font-size:14px;">// 描述 // 给定两个日期&#xff0c;计算这两个日期之间有多少个2月29日&#xff08;包括起始日期&#xff09;。// 只有闰年有2月29日&#xff0c;满足以下一个条件的年份为闰年&#xff1a;// 1. 年份能被4整除但不能被100整除…

vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 问题说明&#xff1a;当安装VS2012之后&#xff0c;原来的.NET 4.0会被替换为.NET 4.5。卸载VS2012时&#xff0c;不会恢复.NET 4.0。 l 当VS2012安装后&#xff0c;VS2010的cvtres.exe就无法使用了。…