1. 顺序表:用一组地址连续的存储单元依次存储线性表的数据元素。
#include <iostream>
#include <malloc.h>
#include <typeinfo>
using namespace std;
#define SIZE 100 //线性表初始存储空间分配量
#define INCREMENT 10 //线性表存储空间分配增量
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int Status;
template <class T>
struct SqList{
private:
T *elem; //存储空间基址
int listsize; //当前分配的存储容量
public:
int Length; //当前list长度
SqList() //无参构造函数
{
elem=(T*)malloc(SIZE*sizeof(T));
if(!elem)
{
cout<<"开辟内存失败!";
exit(OVERFLOW);
}
Length=0;
listsize=SIZE;
}
T& operator[](int i) //重载下标运算符
{
if(i>Length-1)
{
cout<<"索引超出边界"<<endl;
exit(OVERFLOW);
}
return elem[i];
}
Status Insert(int i,T e)
{
//在顺序表中第i个位置插入新的元素e,
//i的合法值为[0,Length]
if(i<0||i>Length)return ERROR;//判断i是否合法
if(Length>=listsize) //如果当前数组超限则自动扩展数组
{
T *newbase=(T*)realloc(elem,
(listsize+INCREMENT)*sizeof(T));
if(!newbase)exit(OVERFLOW);
elem=newbase;
listsize+=INCREMENT;
}
for(int j=Length;j>i;j--)elem[j]=elem[j-1];
elem[i]=e;
Length++;
return OK;
}
Status Delete(int i)
{
//删除顺序表中第i位置的元素
//i合法值[0,Lenght-1]
if(i<0||i>Length-1)return ERROR;//判断i是否合法
for(int j=i;j<Length-1;j++) elem[j]=elem[j+1];
Length--;
return OK;
}
int Find(T e)
{
//在顺序表中查找到第1个与e相同的元素并返回下标
//否则返回-1
for(int i=0;i<Length;i++)
if(elem[i]==e)return i;
return -1;
}
void Merge(SqList<T> la)
{
//与顺序表la归并,得到新的顺序表,必须传递T和自身的T类型相同的顺序表
//if(typeid(la[0])==typeid(elem[0]))cout<<"=="<<endl; 判断类型是否相等
//else cout<<"!="<<endl;
//设两个顺序表的元素都是按照值从小到大排好序的
SqList<T> lc;
if(lc.listsize<Length+la.Length)
{
T *newbase=(T*)realloc(lc.elem,
(Length+la.Length)*sizeof(T));
if(!newbase)exit(OVERFLOW);
lc.elem=newbase;
lc.listsize=Length+la.Length;
}
int i=0,j=0,k=0;
while(i<Length&&j<la.Length)
{
lc.Length++;
if(elem[i]<la[j]) lc[k++]=elem[i++];
else lc[k++]=la[j++];
}
while(i<Length){lc.Length++;lc[k++]=elem[i++];}
while(j<la.Length){lc.Length++;lc[k++]=la[j++];}
elem=lc.elem;
Length=k;
listsize=lc.listsize;
}
};
int main()
{
SqList<int> s;
s.Insert(0,40);
s.Insert(0,30);
s.Insert(0,20);
s.Insert(0,10);
cout<<s.Delete(4)<<endl;
cout<<s[0]<<endl;
cout<<s.Find(10)<<endl;
SqList<int> la;
la.Insert(0,300);
la.Insert(0,200);
la.Insert(0,100);
la.Merge(s);
for(int i=0;i<la.Length;i++)
cout<<la[i]<<" ";
}
2. 链式表:用一组任意的存储单元存储线性表的数据元素(可以连续也可以不连续)。
#include <iostream>
#include <malloc.h>
using namespace std;
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int Status;
template <class T>
struct LNode{
T data; //当前结点的数据
LNode *next; //指向下一结点的指针
LNode(){
data=0;
next=NULL;
}
};
template <class T>
struct LinkList{
private:
LNode<T> *head;
public:
int Length;
LinkList()
{
head=new LNode<T>;
Length=0;
}
T& operator[](int i) //重载下标运算符
{
if(i>Length-1)
{
cout<<"索引超出边界"<<endl;
//throw "索引超出边界";
}
LNode<T> *s=head;
int j=0;
while(j++<=i)s=s->next;
return s->data;
}
//在某位置插入某元素,默认在尾部插入
Status Insert(T e,int i=-1)
{
if(i>Length||i<-1)return ERROR;
LNode<T> *s=(LNode<T> *)malloc(sizeof(LNode<T>));
s->data=e;
s->next=NULL;
int index=(i==-1?Length:i);
LNode<T> *p=head;
int j=0;
while(j++<index)p=p->next;
LNode<T> *q=p->next;
p->next=s;
s->next=q;
Length++;
return OK;
}
//删除某位置的结点
Status Delete(int i)
{
if(i>Length||i<0)return ERROR;
LNode<T> *p=head,*q;
int j=0;
while(j++<i)p=p->next;
q=p->next;
p->next=q->next;
free(q);
Length--;
return OK;
}
//合并两个单链表
void Merge(LinkList &la)
{
//假设单链表la和本体的元素已经从小到大排序
LNode<T> *p=la.head->next,*q=head->next,*r=head;
while(p&&q)
{
if(p->data>q->data)
{
r->next=q;
r=q;
q=q->next;
}
else{
r->next=p;
r=p;
p=p->next;
}
}
r->next=(p==NULL?q:p);//插入剩余段
Length+=la.Length;
//free(la);
}
//查找第一个和参数值相等的元素的索引
int Find(T e)
{
LNode<T> *s=head;
int j=0;
while(s->data!=e&&j++<Length) s=s->next;
return s->data==e?j-1:-1;
}
};
int main()
{
LinkList<int> l,la;
l.Insert(10);
l.Insert(20);
l.Insert(30);
l.Insert(40);
l.Delete(3);
//cout<<l.Length<<endl;
la.Insert(1);
la.Insert(200);
la.Insert(300);
la.Insert(400);
l.Merge(la);
cout<<l.Find(400)<<endl;
for(int i=0;i<l.Length;i++)
cout<<l[i]<<" ";
}
3. 静态链表:用数组描述的链式表。
#include <iostream>
using namespace std;
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int Status;
#define MAXSIZE 1000 //链表最大长度
template <class T>
struct LNode{
T data;
int cur; //游标(相当于*next)
};
template <class T>
struct SLinkList
{
private:
LNode<T> datas[MAXSIZE];//既是备用链表,保存所有未使用过以及被删除的结点,也是数据链表,保存已经插入的数据
int head; //头结点(索引) 头结点不存数据,datas[0]是备用结点的头结点也不存数据,所以可存空间是MAXSIZE-2
public:
int Length;
SLinkList()
{
Length=0;
//将数组datas链成一个备用链表,datas[0].cur为头指针
//0表示空指针
for(int i=0;i<MAXSIZE-1;i++)
datas[i].cur=i+1;
datas[MAXSIZE-1].cur=0;
head=Malloc();
}
T& operator[](int i)
{
if(i>Length-1||i<0){
cout<<"索引无效"<<endl;
}
int j=head,t=0;
while(t++<=i)j=datas[j].cur;
return datas[j].data;
}
int Malloc()
{
//若备用空间链表非空,则返回分配的结点下标,否则返回0
int i=datas[0].cur;
if(datas[0].cur>0)datas[0].cur=datas[i].cur;
return i;
}
void Free(int k)
{
//将下标为k的空闲结点回收到备用链表
datas[k].cur=datas[0].cur;
datas[0].cur=k;
}
Status Insert(T e,int i=-1)
{
if(i>Length||i<-1)return ERROR;
if(Length+1>MAXSIZE)
{
cout<<"数组超限"<<endl;
return ERROR;
}
int index=(i==-1?Length:i);
/*if(Length==0)
{
datas[1].data=e;
datas[1].cur=0;
datas[0].cur=1;
}
else
{
datas[Length+1].data=e;
int j=0,t=0;
while(t++<index){j=datas[j].cur;}
int x=datas[j].cur;
datas[j].cur=Length+1;
datas[Length+1].cur=x;
}*/
int sub=Malloc();//获得新结点下标
datas[sub].data=e;
int j=head,t=0;
while(t++<index){j=datas[j].cur;}
int x=datas[j].cur;
datas[j].cur=sub;
datas[sub].cur=x;
Length++;
return OK;
}
Status Delete(int i)
{
if(i>Length-1||i<0)return ERROR;
int j=head,t=0;
while(t++<i)j=datas[j].cur;
int x=datas[j].cur;
datas[j].cur=datas[x].cur;
Length--;
Free(x);
return OK;
}
int Find(T e)
{
int j=head,t=0;
while(t++<Length)
{
j=datas[j].cur;
if(datas[j].data==e)
return t-1;
}
return -1;
}
void Difference(SLinkList sl)
{
//计算集合(A-B)U(B-A),并将结果保存到本身
for(int i=0;i<sl.Length;i++)
{
int j=head,t=0;
bool isIn=false;
while(t++<Length)
{
j=datas[j].cur;
if(sl[i]==datas[j].data)
{
isIn=true;
Delete(t-1);
break;
}
}
if(!isIn)Insert(sl[i]);
}
}
};
int main()
{
SLinkList<int> sl,s;
sl.Insert(10);
sl.Insert(20);
sl.Insert(30);
sl.Insert(40);
sl.Insert(15,0);
sl.Delete(1);
s.Insert(10);
s.Insert(20);
s.Insert(40);
s.Insert(50);
sl.Difference(s);
cout<<sl.Find(30)<<endl;
for(int i=0;i<sl.Length;i++)
cout<<sl[i]<<" ";
}
4. 循环链表:特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。所以从表中任何一个结点出发都能找到其它结点。
5. 双向链表:结点中有两个指针域,一个指向前驱,一个指向后继。
#include <iostream>
#include <malloc.h>
using namespace std;
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int Status;
template <class T>
struct Node
{
T data;
Node *prior,
*next;
Node()
{
data=0;
prior=NULL;
next=NULL;
}
};
template <class T>
struct DuLinkList
{
private:
Node<T> *head;
public:
int Length;
DuLinkList()
{
head=new Node<T>();
head->next=head;
head->prior=head;
Length=0;
}
T&operator[](int i)
{
if(i<0||i>Length-1)
{
cout<<"索引超限"<<endl;
}
Node<T> *p=head;
int j=0;
while(j++<=i)p=p->next;
return p->data;
}
Status Insert(T e,int i=-1)
{
if(i<-1||i>Length)return ERROR;
Node<T> *s=new Node<T>();//(Node<T>*)malloc(sizeof(Node<T>));
s->data=e;
int index=(i==-1?Length:i);
Node<T> *p=head,*q;
int j=0;
while(j++<index)p=p->next;
q=p->next;
p->next=s;
s->prior=p;
s->next=q;
q->prior=s;
Length++;
return OK;
}
Status Delete(int i)
{
if(i<0||i>Length-1)
{
cout<<"索引不存在"<<endl;
return ERROR;
}
Node<T> *p=head;
int j=0;
while(j++<=i)p=p->next;
p->next->prior=p->prior;
p->prior->next=p->next;
delete p;
Length--;
return OK;
}
};
int main()
{
DuLinkList<int> dl;
dl.Insert(10);
dl.Insert(20);
dl.Insert(30,0);
dl.Delete(1);
for(int i=0;i<dl.Length;i++)
cout<<dl[i]<<" ";
cout<<endl;
}
6.一元多项式的表示和相加
#include <iostream>
#include <stdlib.h>
using namespace std;
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int Status;
string ToChars(int x)
{
//char* itoa(int value,char* string,int base);
//int value 被转换的整数 char* string 转换的后的字符数组 int base 转换进制数
int n=0,t=x;
while(t>0)
{
n++;
t/=10;
}
char str[n];
_itoa(x,str,10);
return string(str);
}
template <class T>
struct Node{//一元多项式中的项结点
int coef; //系数
int expn; //指数
Node<T> *next;
Node(){
coef=0;
expn=0;
next=NULL;
}
};
template <class T>
struct Polynomial
{
private:
Node<T> *head;
public:
int Length;
Polynomial()
{
head=new Node<T>();
Length=0;
}
void Init(int info[][2],int n)
{
Node<T> *t=head;
for(int i=0;i<n;i++)
{
Node<T> *p=new Node<T>();
p->coef=info[i][0];
p->expn=info[i][1];
t->next=p;
t=t->next;
}
}
void Print()
{
Node<T> *t=head;
string s="f(x)=";
while(t->next!=NULL)
{
t=t->next;
s+=ToChars(t->coef)+"x^"+ToChars(t->expn);
s+=(t->next==NULL?"":"+");
}
cout<<s<<endl;
}
void AddPolyn(Polynomial<T> pa)
{
//多项式加法,利用两个多项式的结点构成“和多项式”
Node<T> *p=pa.head->next,*q=head->next,*r=head;
while(p!=NULL&&q!=NULL)
{
if(p->expn<q->expn)
{
r->next=p;
r=p;
p=p->next;
}
else if(p->expn>q->expn)
{
r->next=q;
r=q;
q=q->next;
}
else
{
q->coef+=p->coef;
if(q->coef==0)
{
Node<T> *t=q->next;
delete q;
q=t;
}
else
{
r->next=q;
r=q;
q=q->next;
}
Node<T> *t=p->next;
delete p;
p=t;
}
}
r->next=(p==NULL?q:p);
Length+=pa.Length;
}
};
int main()
{
int info[][2]={
1,1,
2,2,
3,3
};
int info1[][2]={
1,1,
-2,2,
-3,3
};
Polynomial<int> pl,p2;
pl.Init(info,3);
p2.Init(info1,3);
pl.AddPolyn(p2);
pl.Print();
}