数据结构——线性表(第二章)

一、基本概念

1、线性表:简称表,是n(n>=0)个具有相同类型的数据元素的有限序列,线性表中数据元素的个数称为线性表的长度。长度为零时称为空表。

2、线性表的顺序存储结构称为顺序表。

3、单链表:单链表是一组任意的存储单元存放线性表的位置,这组存储单元可以连续也可以不连续,甚至可以零散分布在内存中的任意位置。


下面着重介绍有关单链表的操作:


#include<iostream>
using namespace std;

const int maxsize = 10;

 //  定义单链表的结点   
struct Node
{
	int data;
	struct Node *next;
};

//  linklist 类的声明 
class linklist
{
	public:
		linklist();					//	建立只有头结点的单链表 
		linklist(int a[],int n);	//  建立有N个元素的单链表 
		~linklist();				//  析构函数 
		void insert(int i,int x);	//  在单链表的第 i 个位置插入元素值为 x 的结点 
		int Delete(int  i);			//  在单链表中删除第 i 个结点 
		int locate(int x);			//  在单链表中 按值 查找 元素为x的元素 的位置(序号) 
		void printlist();			//  按序号依次输出各元素 
	private :
		Node *first;				//  单链表的头指针。 
};

linklist::linklist()
{
	first = new Node;				//   生成头结点 
	first ->next=NULL;				//   头结点指针域 置空 
}

linklist::linklist(int a[],int n)
{
	Node *r,*s;
	first = new Node;				//   生成头结点 
	r = first; 						//   尾指针 初始化 
	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 *q = NULL;
	while(first!=NULL)
	{
		q = first;
		first = first->next;
		delete q;
	}
}

void linklist::insert(int i,int x)
{
	Node *p = first,*s = NULL;		//  工作指针p指向头结点 
	int count = 0;
	while(p!=NULL&&count<i-1)		//  查找第 i - 1个结点 
	{
		p = p->next;
		count++;
	}
	if(p==NULL) throw "位置";
	//   	将结点s 插入到p所指的i - 1 之后 
	else{
		s= new Node;s->data= x;
		s->next=p->next;
		p->next = s;
	} 
}

int linklist::Delete(int i)
{
	Node *p = first,*q=NULL;
	int x;
	int count = 0;
	while(p!=NULL&&count<i-1)
	{
		p = p->next;
		count++; 
	}
	//  因为我们上面查找的是i - 1这个位置,删除的却是 i ,所以p-> next 也不能为空 
	if(p == NULL&&p->next ==NULL)    //  这里很重要!!结点p 或 p的后继结点不存在 
		throw"位置";
	else{
		q = p->next;x = q->data;	//   暂存被删结点 
		p->next = q->next;			//   摘链 
		delete q;
		return x;
	} 
}

int linklist::locate(int x)
{
	Node *p = first -> next;		//工作指针p初始化 
	int count = 1;
	while(p != NULL)
	{
		if(p -> data == x) return count;
		p = p -> next;
		count++;
	}
	return 0;
}

void linklist::printlist()
{
	Node  *p = first->next;
	while(p!=NULL)
	{
		cout<<p->data<<" ";
		p=p->next;
	}
	cout<<endl;
}

int main()
{
	int r[5]={1,2,3,4,5};
	linklist L(r,5);		// 建立单链表! 
	cout<<"执行操作前数据为:"<<endl;
	L.printlist();
	try
	{
		L.insert(2,3);       // 在第二个位置插入3. 
	}
	catch(char *s)
	{
		cout<<s<<endl;
	}
	cout<<"执行插入操作后的数据"<<endl;
	L.printlist();
	cout<<"值为5的元素 位置 为:";
	cout<<L.locate(5)<<endl;
	cout<<"执行删除操作前的数据为"<<endl;
	L.printlist();
	try
	{
		L.Delete(1);       // 删除第一个位置的元素; 
	} 
	catch(char *s)
	{
		cout<<s<<endl;
	}
	cout<<"执行删除操作后的数据为:"<<endl;
	L.printlist();
	return 0; 
}

4、循环链表:在单链表中,如果将终端结点的指针域由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为循环单链表,简称循环链表。

5、双链表: 在循环链表中,虽然从任一结点出发可以扫描到其他结点,但要找到其他前驱结点,则需要遍历整个循环链表。如果希望快速确定表中任一结点的前驱结点,可以在单链表的每个结点中再设置一个指向其前驱结点的指针域,这样就形成了双链表。

6、静态链表:静态链表是用数组来表示单链表,用数组元素的下标来模拟单链表的指针。

7、间接寻址:是将数组和指针结合起来的一种方法,它将数组中存储数据元素的单元改为存储指向该元素的指针。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值