探究线性表与链表

线性表概述

线性表(零个或多个数据元素的有限序列)是数据结构种最简单最常用的一种结构。

A1->A2->A3……

线性表的元素之间是有顺序的,例如上述数据表:A2是A1的后继,A2是A3的前驱。

在复杂的线性表种,一个数据元素可由若干个数据项组成。

线性表抽象定义

这里使用类(class)来定义线性表:arraylist

class arraylist
{
private:
public:
	arraylist(){};//初始化
	void emptylist(){};//判断表是否为空
	void clearlist(){};//清空表
	void getelem(){};//获得数据元素
	void insertlist(){};//插入元素
	void deleteelem(){};//删除元素
	void getlength(){};//获取线性表长度
        void getlist(){};//输出线性表
};

线性表应具有以上功能

顺序存储定义
定义:用一段连续的存储单元依次存储线性表的数据元素

/*
CopyRight Lu 2017 ZJ
顺序存储
*/
#include<iostream>
using namespace std;

class arraylist
{
private:
	int size;
	int a[20];
public:
	//初始化
	arraylist(int size=0)
	{
		this->size=size;
	};
	//判断表是否为空
	void emptylist(){};
	//清空表
	void clearlist(){};
	//获得数据元素
	void getelem()
	{
		for(int i=0;i<size;i++)
			cin>>a[i];
	};
	//插入元素
	void insertlist(int arr,int elem)
	{
		if(arr>size)
			a[size+1]=elem;
		else
		{
			if(size<20)
			{
				for(int i=size;i>(arr-1);i--)
					a[i+1]=a[i];
				a[arr]=elem;
			}
			else if(arr>0)
			{
				for(int i=20;i>arr;i--)
					a[i]=a[i-1];
				a[arr]=elem;
			}
			else
			{
				cout<<"wrong"<<endl;
			}
		}	
		size=size+1;
	};
	//删除元素
	void deleteelem(int arr)
	{
		if(arr<=0)
		{
			cout<<"wrong"<<endl;
		}
		else 
		{
			if(arr<size)
			{
				for(int i=arr;i<size;i++)
					a[i]=a[i+1];
			}
			else
			{
				a[arr]=0;
			}
		}
		size=size-1;
	};
	//获取线性表长度
	int getlength()
	{
		cout<<"length="<<size<<endl;
		return size;
	};
	//输出线性表
	void getlist()
	{
		for(int i=0;i<size;i++)
			cout<<a[i]<<" ";
		cout<<endl;
	}
};

void main()
{
	arraylist mylist(5);
	mylist.getelem();
	mylist.deleteelem(3);
	mylist.getlength();
	mylist.getlist();
	mylist.insertlist(2,25);
	mylist.getlength();
	mylist.getlist();
}



运行结果

这里省略了删除和增加的长度检测,要求1<=size<=20

地址计算

数组顺序存储意味着要分配固定长度的数组空间,数组空间长度需要大于线性表的长度。

在数组空间第一个数组元素的地址缺点后(为u),之后的数组元素的地址依次为u+1;u+2;……

顺序存储的优点:无须添加元素间的逻辑关系,可以快速读取任一位置的元素

顺序存储的缺点:插入和删除需要移动大量元素,数据较大时,难以确定存储空间的容量,容易造成存储空间的“碎片”

单链表定义

相比于顺序存储,无需开辟独立连续的空间存储数组元素,只要找到第一个数和指向下一个数的指针。

上述找到第一个数的操作指针为头指针,存储第一个节点的地址。指向头节点(不一定存在)。

/*
CopyRight Lu 2017 ZJ
单链表
*/
#include<iostream>
using namespace std;

//创建节点类
class node
{
public:
	node()
	{
		next=NULL;
	}
	int data;
	node* next;
};

class arraylist
{
private:
	int length;
	node* p;//创建临时节点
	node* head;//头节点
	node* last;//尾节点
public:
	//初始化
	arraylist()
	{
		p=NULL;
		head=NULL;
		last=NULL;
		length=0;
	};
	//判断表是否为空
	bool empty() const
	{
		return length == 0;
	};
	//清空表
	void clear()
	{
		node*q;
		p=head;
		while(p!=NULL)
		{
			q=p->next;
			delete p;
			p=q;
			length--;
		}
		head->next=NULL;
		last=NULL;
		head=NULL;
	};
	//尾插入
	void push_back(int data)
	{
		node* current = new node;
		current->data = data;
		if(last != NULL)
		{
			last->next = current;
		}
		last = current;
		++ length;
		if(head == NULL)
		{
			head = current;
		}
	}
	//获得数据元素
	void getelem(int n)
	{
		for(int i = 0; i < n; ++i)
		{
			int data_current = 0;
			cin>>data_current;
			push_back(data_current);
		}
	};
	//插入元素
	void insertlist(int n,int data)
	{
		p=head;
		node* current = new node;
		current->data = data;
		if(n>length)
			cout<<"wrong"<<endl;
		else
		{
			for(int i=1;i<n;i++)
			{
				p=p->next;
			}
			current->next=p->next;
			p->next=current;
			length++;
		}
	};
	//删除元素
	void deleteelem(int n)
	{
		p=head;
		if(n>length)
			cout<<"wrong"<<endl;
		else
		{
			for(int i=1;i<n-1;i++)
			{
				p=p->next;
			}
			node *q;
			q=p->next;
			p->next=q->next;
			length--;
		}
	};
	//获取线性表长度
	int getlength()
	{
		cout<<"length="<<length<<endl;
		return length;
	};
	//输出线性表
	void getlist()
	{
		p=head;
		while(p!=NULL)
		{
			cout<<p->data<<" ";
			p=p->next;
		}
		if(p==NULL)
			cout<<"NULL";
		cout<<endl;
	};
};

void main()
{
	node mynode;
	arraylist mylist;
	mylist.getelem(3);
	mylist.getlength();
	mylist.getlist();
	mylist.insertlist(2,250);
	mylist.getlength();
	mylist.getlist();
	mylist.deleteelem(2);
	mylist.getlength();
	mylist.getlist();
	mylist.clear();
	mylist.getlength();
	mylist.getlist();
}


运行结果

相比顺序存储,单链表插入删除数据时,无需移动之后数据的存储地址,在处理大量数据时,有着数量级上的优势。

单链表定义


参考 大话数据结构 点击打开链接

未完待续

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值