您的位置:首页 > 理论基础 > 数据结构算法

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

2017-04-19 16:47 405 查看
一、基本概念

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、间接寻址:是将数组和指针结合起来的一种方法。它将数组中存储数据元素的单元改为存储指向该元素的指针。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: