顺序表应用示例

1、假设一个线性表采用顺序表表示,设计一个算法,删除其中所有值等于x的元素,要求算法的时间复杂度为O(n),空间复杂度为O(1)。

解:这里提供两种解法:

解法一:

设删除L中所有值等于x元素后的顺序表为L1,显然L1包含在L中,为此L1重用L的空间。扫描顺序表L,重建L中只包含不等于x的元素,算法过程是置k=0(k用来记录新表中的元素个数),用i从左到右扫描L中所有的元素,当i指向的元素为x时跳过它;否则将其放置在k的位置,即 L->data[k]=L->data[i] , k++
算法如下:

void delnodel(SqList * &L,ElemType x)
{
	int k,i;				//k记录不等于x的元素个数
	for(i=0;i<L->length;i++)
	{
		if(L->data[i]!=x)
		{
			L->data[k]=L->data[i];
			k++;
		}
	}
	L->length=k;
}

解法二:

扫描顺序表L,用i从左到右扫描L中的所有元素,用k记录L中当前等于x的元素的个数,一边扫描L一边统计当前k的值,当i指向的元素为x时k增加1;否则将不为x的元素前移k个位置,即L->data[i-k]=L->data[i]。最后修改L的长度。算法如下:

void delnode2(SqList * &L,ElemType x)
{
	int k=0,i=0;
	while(i<L->length)
	{
		if(L->data[i]==x)
			k++;
		else
			L->data[i-k]=L->data[i];
		i++;
	}
	L->length=L->length-k;
}

2、有一个顺序表L,假设元素类型ElemType为整型,设计一个尽可能高效的算法,以第一个元素为分界线,将所有小于等于它的元素移到该基准的前面,将所有大于它的元素移到该基准的后面。

解法一:

用pivot存放基准,i(初值为0)从左到右扫描,j(初值为L->length-1)从右到左扫描。当i!=j时循环(即循环到i和j指向同一元素时为止):j从右到左找一个小于等于pivot的元素data[j],i从左到右找一个大于pivot的元素data[i],然后将data[i]和data[j]进行交换。当循环结束后再将data[0]和data[i]进行交换,算法如下:

int partition1(SqList * &L)
{
	int i=0,j=L->length;
	ElemType pivot=L->data[0];		//以data[0]为基准
	while(i<j)						//从区间两端交替向中间扫描,直到i=j
	{
		while(i<j && L->data[j]>pivot)		//从右到左扫描,找到一个小于等于pivot的元素
			j--;
		while(i<j && L->data[i]<=pivot)		//从左到右扫描,找到一个大于pivot的元素
			i++;
		if(i<j)
			swap(L->data[i],L->data[j]);	//将找到的这两个元素进行交换
	}
	swap(L->data[i],L->data[0]);		
}

有些读者有可能看不明白,我用图表来展示一下该算法的执行过程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解法二:

用pivot存放基准,i(初值为0)从左到右查找,j(初值为L->length-1)从右到左查找。当i不等于j时循环:j从右向左找一个小于等于pivot的data[j],找到后将data[j]放到data[i]处(用data[j]覆盖data[i]),i从右向左找一个大于pivot的元素data[i],找到后将data[j]放到data[j]处(用data[i]覆盖data[j])。最后让data[i]=pivot。算法如下:

void partition2(SqList * &L)
{
	int i=0,j=L->length-1;
	ElemType pivot=L->data[0];
	while(i<j)						//从区间两端交替向中间扫描,直到i=j
	{
		while(i<j && L->data[j]>pivot)		//从右到左扫描,找到一个小于等于pivot的元素
			j--;
		L->data[i]=L->data[j];
		while(i<j && L->data[i]<=pivot)		//从左到右扫描,找到一个大于pivot的元素
			i++;
		L->data[j]=L->data[i];
	}
	l->data[i]=pivot;	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章