PTA题目:顺序表基本操作

实现顺序表的基本操作,如初始化、插入、删除、输出等。 注意:顺序表中可有重复元素值。 要求:写出三个基本操作函数ListInsert,ListDelete,ListDeleteElem。

顺序表结构与操作函数接口定义:

typedef char ElemType;
typedef struct   //定义顺序表结构
{
    
    
	ElemType data[MaxSize];
   	int length;
} SqList;
void InitList(SqList *&L);	//初始化线性表
void DestroyList(SqList *&L);		//销毁线性表
void DispList(SqList *L);  //顺序输出顺序表元素值。
bool ListInsert(SqList *&L,int i,ElemType e);  //在第i位上插入一个元素e,插入成功时返回true,否则返回false.
bool ListDelete(SqList *&L,int i,ElemType &e); //删除第i个结点, 返回删除的元素值e,且删除成功时返回true,否则返回false
bool ListDeleteElem(SqList *&L,ElemType e);  //删除所有元素值为e的结点,删除成功时返回true,否则返回false

裁判测试程序样例:

#include <stdio.h>
#include <malloc.h>
#define MaxSize 10000
typedef char ElemType;
typedef struct 
{
    
    
	ElemType data[MaxSize];
   	int length;
} SqList;
void InitList(SqList *&L);	//初始化线性表,裁判程序实现,略去不表。
void DestroyList(SqList *&L);		//销毁线性表,裁判程序实现,略去不表。
void DispList(SqList *L);  //顺序输出顺序表元素值。每个结点元素值以空格符间隔,裁判程序实现,略去不表。
bool ListInsert(SqList *&L,int i,ElemType e);  //在第i位上插入一个元素e,插入成功时返回true,插入不成功时返回false. 其中:i为顺序表的逻辑序号。
bool ListDelete(SqList *&L,int i,ElemType &e); //在第i个结点上删除一个元素, 返回删除的元素值e,且删除成功时返回true,删除不成功返回false。其中:i为顺序表的逻辑序号。
bool ListDeleteElem(SqList *&L,ElemType e);  //删除元素值为e的结点,删除成功时返回true,删除 不成功返回false。

int main()
{
    
    
	SqList *L;
	ElemType e,ch;
	int i=1;
	InitList(L);
	while((ch=getchar())!='\n')
	{
    
    
		ListInsert(L,i,ch);  //在L的第i个结点位置上插入ch
		i++;
	}
	DispList(L);
	scanf("\n%d %c",&i,&ch);
	ListInsert(L,i,ch);
	DispList(L);
	scanf("\n%d",&i);	
   	if(ListDelete(L,i,e)) // 删除L的第i个结点
	{
    
    
		printf("delete %dth: %c\n",i,e);
	   	DispList(L);	
   		if(ListDeleteElem(L,e))       // 删除元素值为e的结点
	   		printf("delete \'%c\' \n",e);
		else
			printf("delete \'%c\' failed!\n",e);
	}
	else
		printf("delete %dth failed!\n",i);
	DispList(L);
	DestroyList(L);
}

void InitList(SqList *&L)	//裁判程序实现,略去不表。
{
    
    ...
}
void DestroyList(SqList *&L) //裁判程序实现,略去不表。
{
    
    ...
}
void DispList(SqList *L) //裁判程序实现,略去不表。
{
    
    
...
}

//你的代码将被嵌在这里

输入样例1:

abcdefghia
5 X
1
说明 : 第一行:输入一行字符构造字符顺序表;第二行:在第5个结点处插入字符X的元素;第三行:删除第1个结点元素,并在顺序表中继续删除所有与此结点元素值相等的结点。

输出样例1:

a b c d e f g h i a 
a b c d X e f g h i a 
delete 1th: a
b c d X e f g h i a 
delete 'a' 
b c d X e f g h i 

输入样例2:

abcdef
5 X
0
说明 : 第一行:输入一行字符构造字符顺序表;第二行:在第5个结点处插入字符X的元素;第三行:删除第0个结点元素,并在顺序表中继续删除所有与此结点元素值相等的结点。

输出样例2:

a b c d e f 
a b c d X e f  
delete 0th failed!
a b c d X e f  

分析

每个单函数并不难读者可以自己逐句分析,理解每句代码就好。博主在之前一直有一个测试点过不了。这道题是考察了算法方面的一个点。就是时间复杂度的问题。博主之前在删除重复数据的部分一直是双循环,时间复杂度为n²。那么如何优化算法将这个时间复杂度给减少呢?我查到了下面的这些资料:
图1图2这篇文献里优化后的算法将时间复杂度从n²降到了n,大大提高了算法的效率。最后这道题也完全正确。

答案

bool ListInsert(SqList *&L,int i,ElemType e){
    
    
     if(i <= 0 || i > L->length + 1 || L->length == MaxSize) 
          return false;
      int j; 
      i--; 
      if(i == L->length){
    
    
        L->data[i] = e;
        L->length++;
      }  
      else{
    
    
       for(j = L->length;j > i;j--)
          L->data[j] = L->data[j - 1];
      L->data[i] = e;
      L->length++;
      e = L->data[i - 1];
      }
      return true;
}

bool ListDelete(SqList *&L,int i,ElemType &e){
    
    
    if(i < 1 || i > L->length) 
      return false;
   i--;
   e = L->data[i];
   int k;
   for(k = i;k < L->length;k++)
     L->data[k] = L->data[k + 1];
   L->length--;
   return true;
}

bool ListDeleteElem(SqList *&L,ElemType e){
    
    
    int i=0,j=0,f=0;
	while(i+j<L->length){
    
    
		L->data[i]=L->data[i+j];
		if(L->data[i]==e)j++,f=1;
		else
		i++;
	}
	L->length=L->length-j;
	if(f==0)return false;
	return true;
}

如果觉得博主写得不错的话,就点个赞或者关注吧!

猜你喜欢

转载自blog.csdn.net/qq_45619909/article/details/109145900