严蔚敏数据结构习题10.30

这个快排的话,说实话,之前一直写的都是递归形式的快排,对待非递归的快排,也就是自己要维护一个栈,所以觉得挺有意义的,单开一个博文,记录一下。

先把我之前的递归形式的快排放上来,当然这个也是做了优化的快排,并没有每一次都把轴心元素和找到的元素交换,而是先通过low和high所指的元素之间的相互赋值,从而找到轴心元素应该所在的位置,从而直接一个赋值即可。

具体的步骤如下:

这里的话,将a[low]看作轴心元素,先用一个临时变量tmp保存数组a[low]的值,然后,从high侧开始比较,如果比tmp大,就移动high的指针,如果小的话,直接将这个值赋给low指针所指的值,low指针所指的第一个值是咱们的轴心元素,所以不用担心值的覆盖问题的。同样,low那边的元素也是同样的道理。代码如下:

#include<stdio.h>

//先写一个递归的快排算法

void printArray(int a[],int n);


int partition(int arr[],int low,int high)
{
	printf("%d %d\n", low,high);
	int aim;
	aim = arr[low];

	while(low < high)
	{
		while(low < high && arr[high] >= aim) --high; //先从high开始
		//直到while不满足循环的时候,即存在一个比中间值小的数,此时赋值过来,这里不用交换
		arr[low] = arr[high];	

		while(low < high && arr[low] <= aim) ++low;
		arr[high] = arr[low];

	}


	arr[low] = aim;

	return low;

}

void QSort(int arr[],int low,int high)
{
	if(low < high)
	{
		int middle;
		middle = partition(arr,low,high);
		printf("middle = %d\n",middle );
		QSort(arr,low,middle - 1);
		QSort(arr,middle + 1,high);
	}


}

void quicksort_firstq(int arr[],int n)
{
	QSort(arr,0,n-1);

}





void printArray(int a[],int n)
{
	int i;
	for(i = 0;i < n ; i++)
	{
		printf("%d ",a[i]);

	}

	printf("\n");

}


int main(int argc, char const *argv[])
{
	int a[8]={8,3,6,2,9,5,1,4};
	quicksort_firstq(a,8);

	printArray(a,8);
	
	return 0;
}

但是这道题目确是要求用非递归的方法,有点意思哦~
题目如下:
在这里插入图片描述

(1)

#include<stdio.h>

#define FALSE 0
#define TRUE 1


typedef struct 
{
	int low;
	int high;
	
}SNode;

int partition(int arr[],int low,int high)
{
	int aim;
	aim = arr[low];

	while(low < high)
	{
		while(low < high && arr[high] >= aim) --high; //先从high开始
		//直到while不满足循环的时候,即存在一个比中间值小的数,此时赋值过来,这里不用交换
		arr[low] = arr[high];	

		while(low < high && arr[low] <= aim) ++low;
		arr[high] = arr[low];

	}

	arr[low] = aim;

	return low;

}


void quicksort1(int arr[],int low,int high)
{
	int tag; //判断序列是否有序
	int position;   //轴心元素应该处的位置
	int lnum,rnum;  //左右子序列中元素的个数
	int count;      //栈中元素的个数
	SNode Stack[100]; //栈 0位置不用


	tag = TRUE;
	count = 0;

	while(tag)
	{
		position = partition(arr,low,high);
		if(position == low) //这里要判断是否是一个元素,如果是一个元素则有序,否则就需要进一步排序
		{
			if( (high-low) == 0)
				tag = FALSE;
			else
				low = low + 1;
		}
		if(tag)
		{
			lnum = position - low;
			rnum = high - position;

			if( lnum > 1 || rnum > 1)
			{
				count++;  

				if(lnum <= rnum) //左边的少,则先排左边的,将右边的上下界入栈
				{
					Stack[count].low = position+1;
					Stack[count].high = high;
					high = position - 1;  
				}

				else
				{
					Stack[count].low = low;
					Stack[count].high = position - 1;
					low = position + 1; //先排右边的
				}

			}//if( lnum > 1 || rnum > 1)
		}//if(tag)


		if(!tag || (lnum <= 1 && rnum <= 1))  //已经有序的时候
		{
			if(count)
			{
				low = Stack[count].low;  //将栈中保存的上下界弹出
				high = Stack[count].high;
				count --;  //出栈
				tag = TRUE;  //设定此时栈中无序
			}//if
		}//if

	}//while


}


void quicksort_1(int arr[],int n)
{
	quicksort1(arr,0,n-1);
}

void printArray(int a[],int n)
{
	int i;
	for(i = 0;i < n ; i++)
	{
		printf("%d ",a[i]);

	}

	printf("\n");

}


int main(int argc, char const *argv[])
{
	int a[8]={7,3,6,2,9,5,1,4};
	quicksort_1(a,8);

	printArray(a,8);
	
	return 0;
}

在这里插入图片描述

(2)

第二问,我们在排序之前先进行元素个数的检查

#include<stdio.h>

#define FALSE 0
#define TRUE 1

void printArray(int a[],int n);

//这样写并没有让记录小于3时用比较排序


typedef struct 
{
	int low;
	int high;
	
}SNode;

void swap(int *i,int *j)
{
	int p;
	p = *i;
	*i = *j;
	*j = p;
}

int partition(int arr[],int low,int high)
{
	int aim;
	aim = arr[low];

	while(low < high)
	{
		while(low < high && arr[high] >= aim) --high; //先从high开始
		//直到while不满足循环的时候,即存在一个比中间值小的数,此时赋值过来,这里不用交换
		arr[low] = arr[high];	

		while(low < high && arr[low] <= aim) ++low;
		arr[high] = arr[low];

	}

	arr[low] = aim;

	return low;

}


//这里我理解为冒泡排序吧
void compareSort(int arr[],int low,int high)
{
	int remark;
	int num = high - low + 1;
	do
	{
		remark = FALSE;
		for(int i = low; i < num - 1 ; i++)
		{

			if( arr[i] > arr[i+1] )
			{
				swap( &arr[i] , &arr[i+1] );
				remark = TRUE;

			}
		}

		num -- ;

	}while(remark);

}

void __quicksort2(int arr[],int low,int high)
{
	int tag = TRUE;  //判断序列是否有序
	SNode Stack[100];
	int lnum,rnum;
	int position;
	int i,j;
	int count = 0; //记录栈中元素,要初始一下元素

	while(1)//这里不是tag了
	{
		//先判断待排记录
		if(high - low + 1 <= 3)
		{
			compareSort(arr,low,high);
			//先判断栈里是否有元素,有就弹出
			if(count)
			{
				low = Stack[count].low;
				high = Stack[count].high;
				count --;
			}
			else
				break;
		}
		else
		{
			position = partition(arr,low,high);
			lnum = position - low;
			rnum = high - position;

			count++;

			if( lnum <= rnum ) //左边的元素少,右边入栈
			{
				Stack[count].low = position + 1;
				Stack[count].high = high;
				high = position - 1;
			}
			else
			{
				Stack[count].low = low;
				Stack[count].high = position - 1;
				low = position + 1;
			}


		}
	}
}

		

void quicksort2(int arr[],int n)
{
	__quicksort2(arr,0,n-1);

}
void printArray(int a[],int n)
{
	int i;
	for(i = 0;i < n ; i++)
	{
		printf("%d ",a[i]);

	}

	printf("\n");

}


int main(int argc, char const *argv[])
{
	int a[8]={7,3,6,2,9,5,1,4};
	quicksort2(a,8);

	printArray(a,8);
	
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37414405/article/details/88866334
今日推荐