数据结构——线性表

数据结构——线性表的实现(模板类)

一.顺序表

1.无参构造函数

template<typename T>
SeqList<T>::SeqList( )
{  
    length=0; //表长初始化为0
}

2.有参构造函数

template <class T>  
SeqList::SeqList(T a[ ], int n)
{  
       if (n>MaxSize) throw "参数非法";//不能超出数组最大长度,MaxSize是线性表的最大可存储长度
       for (i=0; i<n; i+ +)  
             data[i]=a[i];
       length=n; //更新表长
 }

3.插入操作

template <class T>  
void SeqList::Insert(int i, T x)//i为在线性表中的位置(1,2,3,4,5...),而非在数组中的位置(0,1,2,3,4...)
{
      if (length>=MaxSize) throw  "上溢";
      if (i<1 | | i>length+1) throw  "位置不合理 ";
      for (j=length; j>=i; j--)//表中元素后移
           data[j]=data[j-1]; 
      data[i-1]=x;
      length++;
}

4.删除操作

template <class T>  
T SeqList::Delete(int i)//i为在线性表中的位置(1,2,3,4,5...),而非在数组中的位置(0,1,2,3,4...)
{
	  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;
}

5.查找操作、判空操作与遍历操作

查找操作分为按值查找(Locate)和按位查找(Get),这三种功能思路比较简单,不再赘述,但应注意判溢。

二.单链表(带头结点)

1.结点

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

2.无参构造函数

template <class T>
LinkList<T>::LinkList()
{
	first=new Node<T>;//生成头结点
	first->next=NULL;//置空
}

3.有参构造函数

1.头插法(倒序)
template <class T>  
LinkList:: LinkList(T a[ ], int n)
{       
    first=new Node<T>;//生成头结点 
    first->next=NULL;   
    Node<T> *s=NULL;
    for (i=0; i<n; i++)
    {
        s=new Node<T>; //生成结点
        s->data=a[i];   //赋初值
        s->next=first->next;   //插在头结点后面     
        first->next=s;
     }
 }

2.尾插法(正序)
template <class T>  
LinkList:: LinkList(T a[ ], int n)
{ 
    first=new Node<T> ; 
    Node<T> *rear=first;//生成指向头结点的尾指针 
    Node<T> *s=NULL;        
    for (i=0; i<n; i++)
    {
        s=new Node<T> ; 
        s->data=a[i];   
        rear->next=s;//插在尾结点后面
        rear=s;       
    }
    rear->next=NULL;     
}

4.插入操作

template <class T>  
 void LinkList::Insert(int i, T x)
 {      
     Node<T> *p=first ;//工作指针  
     Node<T> *s=NULL;
     int count=0;    //计数器
     /*
	第一次循环,工作指针指向第一个元素,count=1,
	当count=i-1时,工作指针指向第i-1个元素,循环结束
	*/
     while (p && count<i-1)//查找第i-1个结点
     {
          p=p->next; 
          count++;
     }
	 if (!p) throw "位置";
   	 else { 
       s=new Node<T>; 
       s->data=x;  
       s->next=p->next;       
       p->next=s;
   }
}

5.删除操作

template <class T>  
T LinkList::Delete(int i)
{
	Node<T> *p=first ; 
	Node<T> *q=NULL ;
	int count=0;  
    while (p && count<i-1) //查找第i-1个结点
    {
         p=p->next;
         count++;
     }
   if (!p | | !p->next) //结点p不存在或其后继不存在
        throw “位置异常”; 
   else {  
         q=p->next; //第i个结点
         T x=q->data;  //暂存被删除结点 
         p->next=q->next; //断开第i个结点,连接第i-1和第i+1个结点  
         delete q; 
         return x;
    }
 }

6.析构函数

template <class T>  
LinkList:: ~LinkList( )
{   
	Node<T> *p=first;
	Node<T> *q=NULL; 
    while (p)//非空时
  {
        q=p;    
        p=p->next;  
        delete q;    
    }
}

7.链表长度

template <typename T>
int LinkList<T>::Length()  
{
    Node<T> *p=first->next;//工作指针初始指向第1个结点
    int count=0;
    while(p)
    {
        p=p->next;
        count++;
    }
    return count;
}

8.查找操作

1.按位查找
template <typename T>
T LinkList<T>::Get(int i)   
{
    Node<T>*p=first->next;
    int count =1;
    while(p&&count<i)
    {
        p=p->next;
        count++;
    }
    if(p==nullptr)
        throw "查找位置错误";
    else
        return p->data;
}
2.按值查找(默认查找第一次出现的)
template <typename T>
int LinkList<T>::Locate(T x) 
{
    Node<T>*p=first->next;
    int count=1;
    while(p!=nullptr)
    {
        if(p->data==x)
            return count;
        p=p->next;
        count++;
    }
    return 0;
}

9.判空操作

template <typename T>
int LinkList<T>::Empty() 
{
    if(first->next==nullptr)
        return 1;
    return 0;
}

10.遍历操作

template<typename T>
void LinkList<T>::PrintList()  
{
    Node <T>*p=first->next;
    while(p!=nullptr)
    {
        cout<<p->data<<'\t';
        p=p->next;
    }
    cout<<endl;
}

三.循环链表(解决前驱问题)

1.插入操作

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

2.循环链表合并(加入尾指针)

LinkList<T>   merge _1(LinkList<T> LA, LinkList<T> LB)
{  /* 将两个链表的首尾相连 */ 
     p =new Node<T> ;
     q =new Node<T>; 
     p=LA; 
     q=LB;  
	 while (p->next! =LA)  p=p->next;   /* 找到表LA的表尾, 用p指向它 */
	 while (q->next! =LB)    q=q->next;  /* 找到表LB的表尾, 用q指向它 */       
     q->next=LA;  /* 修改表LB 的尾指针, 使之指向表LA 的头结点 */ 
     p->next=LB->next;  /* 修改表LA的尾指针, 使之指向表LB 中的第一个结点 */
} 

四.双向链表(关键语句)

1.结点

template <class T>
struct DulNode
{
     T data;
     DulNode<T> *prior, *next;
};

2.插入操作

//p指向第i-1个结点
s->prior=p;//待插入结点的前驱指向第i-1个结点
s->next=p->next;//待插入结点的后继指向第i个结点
p->next->prior=s;//第i个结点的前驱指向待插入结点
p->next=s;//第i-1个结点的后继指向待插入结点

3.删除操作

//p指向第i个结点
(p->prior)->next=p->next;
(p->next)->prior=p->prior;
delete p;

4.无头结点的双向循环链表的构建

#include <iostream>
using namespace std;
template <typename T>
class Node
{
public:
    T data;
    Node<T> *next,*prior;
};
template <typename T>
class DCirLinkList
{
public:
    DCirLinkList();
    DCirLinkList(T a[],int l);
private:
    Node<T> *door;//进入循环的入口
    int length;
};
template<typename T>
DCirLinkList<T>::DCirLinkList()
{
    door=new Node<T>;
    door=nullptr;
    door->next=door;
    door->prior=door;
    length=0;
}
template<typename T>
DCirLinkList<T>::DCirLinkList(T a[],int l)
{
    length=l;
    door=new Node<T>;
    Node<T> *p=door;
    p->data=a[0];
    for(int i=1;i<l;i++){
        Node<T> *t=new Node<T>;
        t->data=a[i];
        p->next=t;
        t->prior=p;
        p=p->next;
    }
    door->prior=p;
    p->next=door;
}
int main()
{
    int a[5]={1,2,3,4,5};
    DCirLinkList<int> x(a,5);

}

五.终极进阶

#include<iostream>
using namespace std;
template <typename T>
class Node{
public:
    T data;
    Node<T> *next;
};
template <typename T>
class LinkList{
public:
    LinkList();
    LinkList(T a[],int n);
    ~LinkList();
    int Length();
    T Get(int i);
    int Locate(T x);
    void Insert(int i,T x);
    T Delete(int i);
    int Empty();
    void PrintList();
private:
    Node<T> *first;

};
template <typename T>
LinkList<T>::LinkList(){
    first=new Node<T>;
    first->next=nullptr;
}
template <typename T>
LinkList<T>::LinkList(T a[],int n){
    first=new Node<T>;
    Node<T> *r=first;
    first->next=nullptr;
    for(int i=0;i<n;i++){
        Node<T> *s=nullptr;
        s=new Node<T>;
        s->data=a[i];
        r->next=s;
        r=s;
    }
    r->next=nullptr;
}
template <typename T>
LinkList<T>::~LinkList(){
    Node<T> *p=first;
    while(first!=nullptr){
        first=first->next;
        delete p;
        p=first;
    }
}
template <typename T>
int LinkList<T>::Length(){
    int count=0;
    Node<T> *p=first->next;
    while(p){
        p=p->next;
        count++;
    }
    return count;
}
template <typename T>
T LinkList<T>::Get(int i){
    Node<T> *p=first->next;
    int count=1;
    while(p&&count<i){
        p=p->next;
        count++;
    }
    if(p==nullptr) throw "查找位置错误";
    else return p->data;
}
template <typename T>
int LinkList<T>::Locate(T x){
    Node<T> *p=first->next;
    int count=1;
    while(p){
        if(p->data==x) return count;
        p=p->next;
        count++;
    }
    return 0;
}
template <typename T>
void LinkList<T>::Insert(int i,T x){
    Node<T> *s=nullptr;
    s=new Node<T>;
    s->data=x;
    Node<T> *p=first;
    int count=0;
    while(p&&count<i-1){
        p=p->next;
        count++;
    }
    if(p==nullptr) throw "插入位置错误";
    else {
        s->next=p->next;
        p->next=s;
    }

}
template <typename T>
T LinkList<T>::Delete(int i){
    T x;
    Node<T> *p=first,*q=nullptr;
    int count=0;
    while(p&&count<i-1){
        p=p->next;
        count++;
    }
    if(!p||!p->next) throw "删除位置错误";
    else {
        q=new Node<T>;
        q=p->next;
        x=q->data;
        p->next=q->next;
        delete q;
        return x;
    }
}
template <typename T>
int LinkList<T>::Empty(){
    if(!first->next) return 1;
    else return 0;
}
template <typename T>
void LinkList<T>::PrintList(){
    Node<T> *p=first->next;
    while(p){
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
int main(){
    int f[]={1,2,3,4,5,6,7};
    LinkList<int> a(f,7);
    a.PrintList();
    cout<<a.Get(3)<<endl;
    a.PrintList();
    cout<<a.Locate(4)<<endl;
    a.PrintList();
    a.Insert(5,9);
    a.PrintList();
    cout<<a.Delete(3)<<endl;
    a.PrintList();
    cout<<a.Empty()<<endl;
    cout<<a.Length();
#include<iostream>
using namespace std;
const int s=100;
template <typename T>
class SeqList{
public:
    SeqList();
    SeqList(T a[],int n);
    ~SeqList();
    int Length();
    T Get(int i);
    int Locate(T x);
    void Insert(int i,T x);
    T Delete(int i);
    int Empty();
    void PrintList();
private:
    T data[s];
    int length;

};
template <typename T>
SeqList<T>::SeqList(){
    length=0;
}
template <typename T>
SeqList<T>::SeqList(T a[],int n){
    if(n>s) throw "超出最大范围";
    for(int i=0;i<n;i++)
        data[i]=a[i];
    length=n;
}
template <typename T>
SeqList<T>::~SeqList(){}
template <typename T>
int SeqList<T>::Length(){
    return length;
}
template <typename T>
T SeqList<T>::Get(int i){
    if(i>s||i<1) throw "查找未知错误";
    return data[i-1];
}
template <typename T>
int SeqList<T>::Locate(T x){
    for(int i=0;i<length;i++)
        if(data[i]==x) return i+1;
    return 0;
}
template <typename T>
void SeqList<T>::Insert(int i,T x){
    if(length==s) 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 <typename T>
T SeqList<T>::Delete(int i){
    if(length==0) throw "overflow";
    if(i<1||i>length) throw "删除位置错误";
    T x=data[i-1];
    for(int j=i-1;j<length-1;j++)
        data[j]=data[j+1];
    length--;
    return x;
}
template <typename T>
int SeqList<T>::Empty(){
    if(length==0) return 1;
    return 0;
}
template <typename T>
void SeqList<T>::PrintList(){
    for(int i=0;i<length;i++)
        cout<<data[i]<<" ";
    cout<<endl;
}
int main(){
    SeqList<int> a;
    cout<<a.Empty()<<endl;
    a.Insert(1,3);
    cout<<a.Empty()<<endl;
    cout<<a.Get(1)<<endl;
    a.Insert(2,2);
    cout<<a.Locate(2)<<endl;
    a.Insert(3,3);
    a.Insert(4,4);
    a.Delete(3);
    a.PrintList();

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值