数据结构——线性表的实现(模板类)
一.顺序表
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();
}