【六】快速排序

(一)递归实现

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

int onequick(int* arr, int left, int right)
{
    
    
	if(arr == NULL || right - left <= 0)
		return -1;
	int tmp = arr[left];
	int i = left;
	int j = right;
	
	while(i < j)
	{
    
    
		while(i < j && arr[j] > tmp) 
		{
    
    
			j--;
		}	
		arr[i] = arr[j];
		
		while(i < j && arr[i] <= tmp)
		{
    
    
			i++;
		}
		arr[j] = arr[i];
		
	}
	arr[i] = tmp;
	
	return i;
}

int quick(int* arr, int left, int right)
{
    
    
	if(arr == NULL || right - left <= 0)
		return -1;
	
	int tmp = onequick(arr, left, right);
	if(tmp - left > 1)
	{
    
    
		quick(arr, left, tmp - 1);
	}
	
	if(right - tmp > 1)
	{
    
    
		quick(arr, tmp + 1, right);
	}
	
}


int main()
{
    
    
	int arr[] = {
    
    2, 4, 2, 5, 6, 3, 1, 9, 7, 8};
	int len = sizeof(arr) / sizeof(arr[0]);
	quick(arr, 0, len - 1);
	
	for(int i = 0; i < len; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

(二)非递归实现

非递归实现快排思想:

把数组一次分治的结果下标分成两份的下标存放在栈中
把下次的一组下标在进行压栈调用onequick

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct Pairdata
{
    
    
	int left;
	int right;
}Pairdata;

typedef struct Stack
{
    
    
	Pairdata* stack_ptr;	//栈地址空间
	int count;				//栈中元素个数
	int size;				//栈容量
}Stack;

//初始化栈
void InitStack(Stack* st, int init_size);
//入栈
void Push(Stack* st, Pairdata value);

//出栈
Pairdata Pop(Stack* st);

//销毁栈
void DestroyStack(Stack* st);
//栈满
int IsFull(Stack* st);
//栈空
int IsEmpty(Stack* st);
//扩容
int ApplyNewSpace(Stack* st);
//=======================================//

//栈满
int IsFull(Stack* st)
{
    
    
	return st->count == st->size;
}
//栈空
int IsEmpty(Stack* st)
{
    
    
	return st->count == 0;
}


//初始化栈
void InitStack(Stack* st, int init_size)
{
    
    
	if (st == NULL)
		return;
	int newsize = init_size > 0 ? init_size : 10;

	st->stack_ptr = (Pairdata*)malloc(sizeof(Pairdata) * newsize);
	if (st->stack_ptr == NULL) return;
	memset(st->stack_ptr, 0, sizeof(Pairdata) * newsize);

	st->size = newsize;
	st->count = 0;

}
//入栈
void Push(Stack* st, Pairdata value)
{
    
    
	if (st == NULL) return;
	//栈满且扩容失败
	if (IsFull(st) && ApplyNewSpace(st)) return;

	st->stack_ptr[st->count] = value;
	st->count++;
}

//出栈
Pairdata Pop(Stack* st)
{
    
    
	if (st == NULL || IsEmpty(st))
		exit(0);
	st->count--;
	return st->stack_ptr[st->count];
}
//扩容
int ApplyNewSpace(Stack* st)
{
    
    
	if (st == NULL) return 0;
	Stack newst;
	newst.size = st->size * 2;
	InitStack(&newst, newst.size);

	//转移数据
	for (int i = 0; i < st->count; i++)
	{
    
    
		newst.stack_ptr[i] = st->stack_ptr[i];
	}
	free(st->stack_ptr);
	st->stack_ptr = newst.stack_ptr;
	return 1;
}

//销毁栈
void DestroyStack(Stack* st)
{
    
    
	if (st == NULL) return;
	free(st->stack_ptr);
	st->stack_ptr = NULL;
	st->size = st->count = 0;
}

int onequick(int* arr, int left, int right)
{
    
    
	if (NULL == arr || right - left <= 0)
		return -1;
	int i = left;
	int j = right;
	int tmp = arr[left];

	while (i < j)
	{
    
    
		while (i < j && arr[j] > tmp)
		{
    
    
			j--;
		}
		arr[i] = arr[j];

		while (i < j && arr[i] <= tmp)
		{
    
    
			i++;
		}
		arr[j] = arr[i];
	}
	arr[i] = tmp;
	return i;
}

int quick(int* arr, int left, int right)
{
    
    
	if (arr == NULL || right - left <= 0)
		return -1;
	Stack st;
	//st_size通过计算得到onequick的次数
	int st_size = 2 * ((int)(log10)(right - left + 1) / log10(2) + 1);
	InitStack(&st, st_size);

	Pairdata value = {
    
     left, right};
	Push(&st, value);

	while (!IsEmpty(&st))
	{
    
    
		value = Pop(&st);
		int tmp = onequick(arr, value.left, value.right);
		if (tmp - value.left > 1)
		{
    
    
			Pairdata left_value = {
    
     value.left, tmp - 1 };
			Push(&st, left_value);
		}

		if (value.right - tmp > 1)
		{
    
    
			Pairdata right_value = {
    
     tmp + 1, value.right };
			Push(&st, right_value);
		}
	}

	DestroyStack(&st);
}

int main()
{
    
    
	int arr[] = {
    
     2, 4, 2, 5, 6, 3, 1, 9, 7, 8 };
	int len = sizeof(arr) / sizeof(arr[0]);
	quick(arr, 0, len - 1);

	for (int i = 0; i < len; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

结果:
在这里插入图片描述

Guess you like

Origin blog.csdn.net/xiaoxiaoguailou/article/details/121171708