代码一览:
stack.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack
{
STDataType *a;
int top;
int capacity;
}ST;
void StackInit(ST *ps);
void StackDestory(ST *ps);
void StackPush(ST *ps, int x);
void StackPop(ST *ps);
STDataType StackTop(ST *ps);
int StackSize(ST *ps);
bool StackEmpty(ST *ps);
stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"
void StackInit(ST *ps)//初始化
{
ps->a = (STDataType*)malloc(sizeof(STDataType)* 4);//先创建4个STDataType大小的内存
if (ps->a == NULL)
{
printf("malloc fail!\n");
exit(-1);
}
ps->top = 0;//top初始为0时,top指向的就不是栈尾元素,而是栈尾的下一个元素
ps->capacity = 4;//数组的空间大小为4
}
void StackDestory(ST *ps)//销毁
{
assert(ps);//判断ps是否为空,如果他为空就说明栈还没有创建,也就不用销毁
free(ps->a);//释放数组a的空间
ps->a = NULL;//让指针*a 指向空
ps->top = ps->capacity = 0;
}
void StackPush(ST *ps, int x)//入栈
{
assert(ps);
//满了,得增容
if (ps->top == ps->capacity)//注意:top从0开始的。并且top指向栈尾元素的下一个地址
{
STDataType *tmp = (STDataType*)realloc(ps->a, sizeof(STDataType)*ps->capacity * 2);
//设置tmp,申请空间成功后,将其赋给ps->a
//如果直接用ps->a,申请内存失败后,ps->a就不对劲了
if (tmp == NULL)//判断是否申请成功
{
printf("realloc fail\n");
exit(-1);
}
else
{
ps->a = tmp;
ps->capacity *= 2;//扩大为原来的2倍
}
}
ps->a[ps->top] = x;
ps->top++;
}
void StackPop(ST *ps)//出栈
{
assert(ps);
assert(ps->top > 0);//判断是否栈空
ps->top--;
}
STDataType StackTop(ST *ps)//取栈顶元素(并不删除栈顶元素)
{
assert(ps);
assert(ps->top > 0);//判断是否栈空
return ps->a[ps->top - 1];
}
int StackSize(ST *ps)//求栈中元素个数
{
assert(ps);
return ps->top;
}
bool StackEmpty(ST *ps)//判断是否为空
{
assert(ps);
return ps->top == 0;
}
test1:
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"
int GetMidIndex(int* a, int left, int right)
{
int mid = (left + right) >> 1;
if (a[left] < a[mid])
{
if (a[mid] < a[right])
{
return mid;
}
else if (a[left] > a[right])
{
return left;
}
else
{
return right;
}
}
else // a[left] > a[mid]
{
if (a[mid] > a[right])
{
return mid;
}
else if (a[left] < a[right])
{
return left;
}
else
{
return right;
}
}
}
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
int PartSort1(int* a, int left, int right)
{
int index = GetMidIndex(a, left, right);
Swap(&a[left], &a[index]);
int begin = left;
int end = right;
int piovt = begin;
int key = a[begin];
while (begin < end)
{
while (begin < end)
{
if (a[end] < key)
{
break;
}
end--;
}
a[piovt] = a[end];
piovt = end;
while (begin < end)
{
if (a[begin] > key)
{
break;
}
begin++;
}
a[piovt] = a[begin];
piovt = begin;
}
piovt = begin;
a[piovt] = key;
return piovt;
}
void QuickSortNonR(int* a, int n)
{
ST st;
StackInit(&st);
StackPush(&st, n - 1);
StackPush(&st, 0);
while (!StackEmpty(&st))
{
int left = StackTop(&st);
StackPop(&st);
int right = StackTop(&st);
StackPop(&st);
int Index=PartSort1(a, left, right);
if (Index + 1 < right)
{
StackPush(&st, right);
StackPush(&st, Index+1);
}
if (left < Index - 1)
{
StackPush(&st, Index-1);
StackPush(&st, left);
}
}
StackDestory(&st);
}
int main()
{
int a[10] = { 4, 2, 8, 6, 1, 9, 0, 3, 5, 7 };
int n = sizeof(a) / sizeof(int);
QuickSortNonR(a, n);
for (int i = 1; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
分析:partsort1 函数即挖坑法,前面有文章说过;
下面就 void QuickSortNonR(int* a, int n) 函数做如下分析:
略;