数据结构——线性表

本文介绍了线性表的概念,包括其定义、长度和空表状态。重点讲解了两种线性表的存储结构:顺序表和单链表。顺序表通过连续的存储单元存放元素,适合进行插入操作,而单链表则采用动态存储分配,通过指针链接元素,便于插入和删除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线性表: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值