线性表练习题

顺序表与单链表对比

题目

请说明顺序表和单链表有何优缺点,并分析下列情况采用何种存储结构更好些。
①若线性表的总长度基本稳定,且很少进行插入和删除,但要求以最快的速度存取线性表中的元素。
②如果n个线性表同时并存,并且在处理过程中各表的长度会动态发生变化。

答案

顺序表:

  • 优点:
    1.无需为表示表中元素之间的逻辑关系而增加额外的存储空间
    2.随机存取:可以快速存取表中任一位置的元素
  • 缺点:
    1.表的容量难以确定,表的容量难以扩容
    2.插入和删除操作需要移动大量元素

单链表:

  • 优点:
  • 缺点:

①顺序表
②单链表

顺序表有序插入

题目

已知顺序表L中的元素递增有序排列,设计算法将元素x插入到表L中并保持表L仍递增有序。

代码

#include <iostream>

using namespace std;
const int MaxSize=100;
using namespace std;
template<class T>
class SeqList{
private:
    int length;
    T data[MaxSize];
public:
    SeqList(){}
    SeqList(T data[],int length);
    ~SeqList(){}
    int getLength();
    T get(int i);
    int getIndex(T x);
    void Insert(T x,int i);
    T Delete(int i);
    int isEmpty();
    void printList();
};
template<class T>
SeqList<T>::SeqList(T d[],int length){
    this->length=length;
    for(int i=0;i<length;i++)
        data[i]=d[i];
}
template<class T>
int SeqList<T>::getLength(){
    return length;
}
template<class T>
T SeqList<T>::get(int i){
    if(i<1||i>length)
        throw"查找位置非法";
    return data[i-1];
}
template<class T>
int SeqList<T>::getIndex(T x){
    for(int i=0;i<length;i++){
        if(data[i]==x)
            return i+1;
    }
    return -1;
}
template<class T>
void SeqList<T>::Insert(T x,int i){
    //注意检查操作合法性
    if(length==MaxSize) throw"上溢";
    if(i<1||i>length+1) throw"插入位置错误";
    for(int j=length;j>=i;j--){
        data[j]=data[j-1];
    }
    data[i-1]=x;
    length++;
}
template<class T>
T SeqList<T>::Delete(int i){
    T x;
    //注意检查操作合法性
    if(length==0) throw"下溢";
    if(i<1||i>length) throw"删除位置错误";
    x=data[i-1];
    for(int j=i;j<length;j++){
        data[j-1]=data[j];
    }
    length--;
    return x;
}
template<class T>
int SeqList<T>::isEmpty(){
    return length==0?1:0;
}
template<class T>
void SeqList<T>::printList(){
    for(int i=0;i<length;i++){
        cout<<i+1<<":"<<data[i]<<endl;
    }
}
int main()
{
    int a[9]={0,1,2,4,5,6,7,8,9};
    SeqList<int> sl(a,9);
    int x=3,i=1;
    while(sl.get(i)<=x){
        i++;
    }
    sl.Insert(x,i);
    sl.printList();
    return 0;
}

就地逆置

题目

试分别以顺序表和单链表作存储结构,各编写一个实现线性表就地逆置的算法。

代码

顺序表

const int MaxSize=10;    //10只是示例性的数据,可以根据实际问题具体定义
class SeqList
{
public:
   SeqList( ){length=0;}       //无参构造函数,创建一个空表
   SeqList(int a[ ], int n);       //有参构造函数
   void Insert(int i, int x);   //在线性表中第i个位置插入值为x的元素
   int Delete(int i);        //删除线性表的第i个元素
   int Locate(int x);       //按值查找,求线性表中值为x的元素序号
   void Reverse();
   void PrintList( );      //遍历线性表,按序号依次输出各元素
private:
   int data[MaxSize];      //存放数据元素的数组
   int length;            //线性表的长度
};

SeqList::SeqList(int a[ ], int n)
{
      if (n>MaxSize) throw "参数非法";
      for (int i=0; i<n; i++)
        data[i]=a[i];
      length=n;
}

void SeqList::Insert(int i, int x)
{
      if (length>=MaxSize) throw "上溢";
      if (i<1 || i>length+1) throw "位置非法";
      for (int j=length; j>=i; j--)
        data[j]=data[j-1];   //注意第j个元素存在数组下标为j-1处
      data[i-1]=x;
      length++;
}

int SeqList::Delete(int i)
{
      if (length==0) throw "下溢";
      if (i<1 || i>length) throw "位置非法";
      int x=data[i-1];
      for (int j=i; j<length; j++)
        data[j-1]=data[j];   //注意此处j已经是元素所在的数组下标
      length--;
      return x;
}

int SeqList::Locate(int x)
{
      for (int i=0; i<length; i++)
        if (data[i]==x)  return i+1 ;  //下标为i的元素等于x,返回其序号i+1
      return 0;  //退出循环,说明查找失败
}

void SeqList::Reverse(){
    int temp;
    for(int i=0;i<length>>1;i++){
        temp=data[i];
        data[i]=data[length-i-1];
        data[length-i-1]=temp;
    }
}

void SeqList::PrintList( )
{
  for (int i=0; i<length; i++)
	cout<<data[i]<<"  ";
  cout<<endl;
}

单链表
利用头插法进行单链表的逆置

#include <iostream>
using namespace std;

template<class T>
struct Node
{
	T data;
	Node<T> *next;
};

template<class T>
class LinkList
{
public:
	LinkList();
	LinkList(T a[], int n);
	~LinkList();
	void PrintList();
	T Get(int i);
	void Insert(int i, T x);
	void Delete(int i);
public:
	Node<T> *first;
};

template<class T>
LinkList<T>::LinkList()
{
	first=new Node<T>;
	first->next=NULL;
}

template<class T>
LinkList<T>::LinkList(T a[], int n)
{
	first=new Node<T>;
	Node<T> *r=first;
	for(int i=0;i<n;i++)
	{
		Node<T> *s=new Node<T>;
		s->data=a[i];
		r->next=s;
		r=s;
	}
	r->next=NULL;
}

template<class T>
LinkList<T>::~LinkList()
{
	while(first!=NULL)
	{
		Node<T> *q=first;
		first=first->next;
		delete q;
	}
}

template<class T>
void LinkList<T>::PrintList()
{
	Node<T> *p=new Node<T>;
	p=first->next;
	while(p!=NULL)
	{
		cout<<p->data<<" ";
		p=p->next;
	}
}

template<class T>
T LinkList<T>::Get(int i)
{
	Node<T> *p=first->next;
	int count=1;
	while(p!=NULL&&count<i)
	{
		p=p->next;
		count++;
	}
	if(p==NULL) throw "查找位置异常";
	else return p->data;
}

template<class T>
void LinkList<T>::Insert(int i, T x)
{
	Node<T> *p=first;
	int count=0;
	while(p!=NULL&&count<i-1)
	{
		p=p->next;
		count++;
	}
	if(p==NULL) throw "插入位置异常";
	else
	{
		Node<T> *s=new Node<T>;
		s->data=x;
		s->next=p->next;
		p->next=s;
	}
}

template<class T>
void LinkList<T>::Delete(int i)
{
  Node<T> *p;
  int j;
  p=first ; j=0;  //工作指针p初始化
  while (p!=NULL && j<i-1)  //查找第i-1个结点
  {
    p=p->next;
    j++;
  }
  if (p==NULL || p->next==NULL) throw "删除位置异常";  //结点p不存在或结点p的后继结点不存在
  else {
    Node<T> *q;
	T x;
    q=p->next; x=q->data;  //暂存被删结点
    p->next=q->next;  //摘链
    delete q;
  }
}
template<class T>
void Rerverse(Node<T> *first){
    //从链表的第二个元素开始摘,然后头插入链表中
    Node<T> *p=first->next,*s=NULL;
    if(p==NULL) throw "空表";
    if(p->next==NULL) return;
    while(p->next!=NULL){
        s=p->next;
        p->next=s->next;

        s->next=first->next;
        first->next=s;

    }
}
template<class T>
Node<T>* Copy(Node<T> *oFirst){
    Node<T> *p=oFirst->next;
    Node<T> *nFirst=new Node<T>;
    Node<T> *s=nFirst;
    Node<T> *t=NULL;

    while(p!=NULL){
        t=new Node<T>;
        t->data=p->data;

        s->next=t;
        s=s->next;

        p=p->next;
    }
    t->next=NULL;
    return nFirst;
}
int main()
{
	int a[]={1,2,3,4,5};
    LinkList<int> test(a,5);
	cout<<"线性表a的初始状态:"<<endl;
	test.PrintList();

	cout<<endl<<"复制线性表a到线性表p,再逆置线性表a。"<<endl;
	Node<int> *p=new Node<int>;
	p=Copy(test.first)->next;
    Rerverse(test.first);

	cout<<"线性表a的状态:"<<endl;
	test.PrintList();

	cout<<endl<<"线性表p的状态:"<<endl;
	while(p!=NULL)
	{
		cout<<p->data<<" ";
		p=p->next;
	}

	return 0;
}


删除有序单链表某区间元素

题目

已知单链表中各结点的元素值为整型且递增有序,设计算法删除链表中大于mink且小于maxk的所有元素,并释放被删除结点的存储空间。

代码

#include <iostream>

using namespace std;
template<class T>
struct Node{
    T data;
    Node<T> *next;
};
template<class T>
class LinkList{
public:
	LinkList();
	LinkList(T a[],int n);
	~LinkList();
	int Length();
	T Get(int i);
	void Set(int i,T x);
	int Locate(T x);
	void Insert(int i,T x);
	T Delete(int i);
	int Empty();
	void PrintList();
private:
    Node<T> *first;
};
template<class T>
LinkList<T>::LinkList(){
    first=new Node<T>;
    first->next=nullptr;
}
template<class T>
LinkList<T>::LinkList(T a[],int n){
    //头插法
    /*
    first=new Node<T>;
    first->next=nullptr;
    for(int i=0;i<n;i++){
        Node<T> *p=nullptr;
        p=new Node<T>;
        p->data=a[i];
        p->next=first->next;
        first->next=p;
    }
    */

    //尾插法
    first=new Node<T>;
    Node<T> *p=first,*s=nullptr;
    for(int i=0;i<n;i++){
        s=new Node<T>;
        s->data=a[i];
        p->next=s;
        p=s;
    }
    p->next=nullptr;
}
template<class T>
LinkList<T>::~LinkList(){
    Node<T> *p=nullptr;
    while(first!=nullptr){
        p=first;
        first=first->next;
        delete p;
    }
}
template<class T>
int LinkList<T>::Length(){
    int cnt=1;
    Node<T> *p=first->next;
    while(p->next!=nullptr){
        cnt++;
        p=p->next;
    }
    return cnt;
}
template<class T>
T LinkList<T>::Get(int i){
    int cnt=1;
    Node<T> *p=first->next;
    while(cnt<i&&p!=nullptr){
        p=p->next;
        cnt++;
    }
    //别漏了还有异常这种情况
    if(p==nullptr) throw"查找位置错误";
    else return p->data;
}
template<class T>
int LinkList<T>::Locate(T x){
    Node<T> *p=first->next;
    int pos=1;
    while(p!=nullptr){
        if(p->data==x)  return pos;
        p=p->next;
        pos++;
    }
    return 0;
}
template<class T>
void LinkList<T>::Insert(int i,T x){
    Node<T> *p=first;
    int cnt=0;
    //要将数据插入到第i个位置,就要找到第i-1个位置再做插入操作
    while(cnt<i-1&&p!=nullptr){
        p=p->next;
        cnt++;
    }
    if(p==nullptr)  throw"插入位置有误";
    else{
        Node<T> *s=new Node<T>;
        s->next=p->next;
        s->data=x;
        p->next=s;
    }

}
template<class T>
T LinkList<T>::Delete(int i){
    Node<T> *p=first;
    int cnt=0;
    //要删除第i个元素,就要找到第i-1个位置,再做删除操作
    while(cnt<i-1&&p!=nullptr){
        p=p->next;
        cnt++;
    }
    //p->next==nullptr:p不存在后继结点
    if(p==nullptr||p->next==nullptr)  throw"删除位置有误";
    else{
        Node<T> *s=p->next;
        T data=s->data;
        p->next=s->next;
        delete s;
        return data;
    }

}
template<class T>
int LinkList<T>::Empty(){
    if(first->next==nullptr)
        return 1;
    return 0;
}
template<class T>
void LinkList<T>::PrintList(){
    Node<T> *p=first->next;
    while(p!=nullptr){
        cout<<p->data<<endl;
        p=p->next;
    }
}
template<class T>
void LinkList<T>::Set(int i,T x){
    int cnt=1;
    Node<T> *p=first->next;
    while(cnt<i&&p!=nullptr){
        p=p->next;
        cnt++;
    }
    if(p==nullptr) throw"位置错误";
    else{
        p->data=x;
    }
}
int main()
{
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    LinkList<int> ll(a,10);
    int mink=4,maxk=9;
    int i=1;
    while(ll.Get(i)<=mink){
        i++;
    }
    while(ll.Get(i)<maxk){
        ll.Delete(i);
    }
    ll.PrintList();
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值