线性表概述
线性表(零个或多个数据元素的有限序列)是数据结构种最简单最常用的一种结构。
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(); }
运行结果
相比顺序存储,单链表插入删除数据时,无需移动之后数据的存储地址,在处理大量数据时,有着数量级上的优势。
单链表定义
参考 大话数据结构 点击打开链接
未完待续