线性表:n个具有相同类型的数据元素的有限序列
长度:线性表中数据元素的个
空表:长度等于零的线性表
相邻数据元素的序偶关系,a1无前驱,an无后继
顺序表sequential list
用一段地址连续的存储单元,依次存储线性表中的数据元素
线性表中元素序号是从1开始的,线性表中第i个元素存储在数组中下标为i-1的位置
数组需要分配固定长度的数组空间,数组的长度要大于当前线性表的长度(线性表中可以进行插入操作),数组长度MaxSize>线性表长度length
顺序表的实现
const int MaxSize=100;
class SeqList
{
public:
private:
DataType data[MaxSize]; //存放数据元素的数组
int length; //线性表的长度
}
SeqList :: SeqList() //表的初始化,建一个空表
{
length=0;
}
SeqList :: SeqList(DataType a[ ], int n) //建立顺序表
{
if (n > MaxSize) throw "参数非法"; //抛出异常,throw总是出现在函数体中,用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到
for (int i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
int SeqList :: Empty() //判空,只需判断length是否为0
{
if(length==0 return 1;
else return 0;
}
int SeqList :: Length() //长度
{
return length;
}
void SeqList :: PrintList() //遍历操作
{
for(int i=0;i<length;i++)
cout<<data[i]<<"\t";
cout<<endl;
}
DataType SeqList :: Get(int i) //按位查找
{
if(i<1 && i>length)throw"查找位置非法",
else return datd[i-1];
}
void LinkList :: Insert(int i, DataType x) //插入操作
{
Node *p=first, *s=NULL;
int count=0;
while(p!=NULL && count<i-1) //查找第i-1个结点
{
p=p->next; //工作指针p后移
count++;
}
if(p==NULL) throw"插入位置错误"; //没有找到第i-1个结点
else{
s=new Node;
s->data=x; //申请结点s,数据域为x
s->next=p->next;
p->next=s; //将结点s插入到结点p之后
}
}
链式存储结构
类似于叫号,不用排队,但不仅要存放自己的数据还要存放一个指针
单链表singly linked list
动态存储分配—>运行时分配空间
逻辑次序和物理次序不一定相同;元素之间的逻辑关系用指针表示
data:存储数据元素
next:储存指向后继节点的地址
头指针first:指向第一个结点的储存地址
尾标志:终端结点的指针域为空
空表:first=NULL
头结点:在第一个元素结点之间附设一个类型相同的结点node(简化了对边界的处理——插入、删除、构造等)
//结点结构定义
struct Node
{
DataType data;
struct Node *next;
}Node;
*p.next = p->next
LinkList :: LinkList() //初始化单链表
{
first = new Node; //生成头结点
first->next = NULL; //头结点的指针域置空
}
int LinkList :: Empty() //空单链表满足条件
{
if(first->next == NULL) return 1;
else return 0;
}
void LinkList :: PrintList() //遍历操作
{
Node *p = first->next; //工作指针p初始化,若直接使用头指针first(标识单链表的开始),数完一遍,线性表就没了
while(p != NULL)
{
cout<<p->data<<"\t";
p = p->next; //工作指针p后移,不能写成p++
}
cout<<endl;
}
int LinkList :: Length() //求长度
{
Node *p = first->next; //工作指针初始化
int count = 0; //累加器初始化
while(p != NULL)
{
count++;
p = p->next;
}
return count; //注意count的初始化和返回值之间的关系
}
DataType LinkList :: Get(int i) //按位查找
{
Node *p = first->next; //工作指针初始化
int count = 1; //累加器count初始化
while(p != NULL && count<i)
{
p = p->next; //工作指针p后移
count++;
}
if(p == NULL) throw "查找位置错误" ;
else return p->data;
}
int LinkList :: Locate(DataType x) //按值查找
{
Node *p = first->next; //工作指针初始化
int count = 1; //累加器count初始化
while(p != NULL)
{
if(p->data == x) return count; //查找成功,结束函数并返回序号
p = p->next;
count++;
}
return 0; //退出循环表明查找失败
}
void LinkList :: Insert(int i, DataType x) //插入操作
{
Node *p = first, *s = NULL;
int count = 0;
while (p != NULL && count<i-1) //查找第i-1个结点
{
p = p->next; //工作指针p后移
count++;
}
if (p == NULL) throw "插入位置错误"; //没有找到第i-1个结点
else{
s = new Node;
s->data = x; //申请结点s,数据域为x
s->next = p->next;
p->next = s; //将结点s插入到结点p之后
}
}
DataType LinkList :: Delete(int i) //删除操作
{
DataType x;
Node *p = first, *q = NULL;
int count = 0;
while(p != NULL && count<i-1) //查找第i-1个结点
{
p = p->next;
count++;
}
if(p == NULL || p->next == NULL)
throw "删除位置错误";
else{
q = p->next;
x = q->data; //暂存被删结点
p->next = q->next; //摘链
delete q;
return x;
}
}
void LinkList :: LinkListHead(DataType a[],int n) //头插法
{
first = new Node;
first->next = NULL; //初始化一个空链表
Node *s = NULL;
for(int i = 0; i<n; i++)
{
s = new Node;
s->data = a[i];
s->next = first->next;
first->next = s; //将结点s插入头结点后
}
}
LinkList :: LinkListRear(DataType a[],int n) //尾插法
{
first = new Node; //生成头结点
Node *r = first, *s = NULL; //尾指针初始化
for(int i = 0; i<n; i++)
{
s = new Node;
s->data = a[i];
r->next = s;
r = s; //将结点s插入终端结点后
}
r->next = NULL; //单链表建立完毕,将终端结点的指针域置空
}
LinkList :: ~LinkList() //析构函数,销毁单链表
{
Node *p = first;
while (first != NULL) //释放每一个结点的储存空间
{
first = first->next; //first指向被释放结点的下一个结点
delete p;
p = first; //工作指针p后移
}
}
单链表的使用
#include <iostream>
using namespace std;
#define DataType int
struct Node
{
DataType data;
Node *next;
};
class LinkList
{
public:
LinkList(); //建立只有头结点的空链表
void LinkListHead(DataType a[],int n); //头插法建立n个元素的空链表
LinkListRear(DataType a[],int n); //尾插法建立n个元素的空链表
~LinkList(); //析构函数
int Length(); //求单链表的长度
DataType Get(int i); //按位查找,查找第i个结点的元素值
int Locate(DataType x); //按值查找,查找值为x的元素符号
void Insert(int i,DataType x); //插入操作,在第i个位置插入值为x的结点
DataType Delete(int i); //删除操作,删除第i个结点
int Empty(); //判断线性表是否为空
void PrintList(); //遍历操作,按序号依次输出各元素
private:
Node *first; //单链表的头指针
};
//。。。。。
int main()
{
int r[5]={1,2,3,4,5},i,x;
LinkList L;
L.LinkListHead(r,5);
L.LinkListRear(r,5); //只运行尾插法
cout<<"当前线性表为";
L.PrintList();
cout<<"线性表长度:"<<L.Length()<<endl;
try
{
L.Insert(2,8);
cout<<"插入后线性表为:";
L.PrintList();
}catch(char *str) {cout<<str<<endl;}
cout<<"当前线性表的长度"<<L.Length()<<endl;
cout<<"输入查找元素值";
cin>>x;
i = L.Locate(x);
if (i>0)
cout<<"元素"<<x<<"的位置为:"<<i<<endl;
else
cout<<"单链表中没有元素"<<x<<endl;
try
{
cout<<"请输入要删除第几个元素:";
cin>>i;
x = L.Delete(i);
cout<<"删除的元素是:"<<x<<",执行删除操作后的数据为:";
L.PrintList();
}catch(char *str) {cout<<str<<endl; }
return 0;
}