数据结构-第一部分.ppt
《数据结构-第一部分.ppt》由会员分享,可在线阅读,更多相关《数据结构-第一部分.ppt(272页珍藏版)》请在三一办公上搜索。
1、1,第一部分 线性表,具有线性关系的数据集合的处理包括三部分内容线性表栈队列,2,第二章 线性表,线性表的概念线性表的实现线性表类的实现STL中线性表的实现,3,线性表的概念,线性表是N个具有相同特征的结点A0,A1,AN-1构成的集合。在这个集合中,除了A0 和AN-1 外,每个元素都有唯一的前趋和后继。对于每个Ai,它的前驱是Ai-1,它的后继是Ai+1。A0只有后继没有前驱,AN-1只有前驱没有后继。表的术语:N为表的大小A0称为首结点,AN-1称为尾结点空表:元素个数为零的表。位置:元素Ai在表中的位置为i,4,表的基本操作,创建一个线性表create():创建一个空的线性表;清除一个
2、线性表clear():删除线性表中的所有数据元素;求线性表的长度length():返回线性表的长度;在第i个位置插入一个元素insert(i,x):使线性表从(a0,a1,ai-1,ai,an-1)变成(a0,a1,ai-1,x,ai,an-1),参数i的合法取值范围是0到n;,5,删除第i个位置的元素remove(i):使线性表从(a0,a1,ai-1,ai,ai+1 an-1)变成(a0,a1,ai-1,ai+1,an-1),参数i的合法取值范围是0到n-1;搜索某个元素在线性表中是否出现search(x):在线性表中搜索x是否出现,并返回x的位置;访问线性表的第i个元素visit(i):
3、返回线性表中第i个数据元素的值;遍历线性表运算traverse():按序访问线性表的每一数据元素。,6,第二章 线性表,线性表的概念线性表的实现线性表类的实现STL中线性表的实现,7,线性表的实现,线性表的顺序实现线性表的链接实现,8,线性表的顺序存储结构,线性表中结点存放在存储器上一块连续的空间中。借助存储空间的连续性,结点可以按照其逻辑顺序依次存放。结点存放的物理位置和它的逻辑位置是一致的。线性表的顺序实现通常称为顺序表。,9,线性表的顺序存储,在程序设计语言中,一块连续的存储空间可以用一个数组实现。由于线性表中的元素个数是动态的,因此采用了动态数组。保存一个动态数组,需要两个变量:指向线
4、性表元素类型的指针,数组规模(容量),数组中的元素个数(表长)。线性表必须支持插入或删除,在申请空间时要留有余地。一般要比实际元素个数多一点。,10,顺序表的运算实现,length():只需要返回length的值visit(i):返回datai的值traverse():输出数组data的前length个元素clear():只要将length置为0即可create(maxSize):申请一个maxSize大小的动态数组,11,search 运算的实现,int search(x)for(num=0;num length;+num)if(datanum=x)break;if(num=length)n
5、um=-1;return num;,12,insert(i,x)运算的实现,在插入时,表长会增加。当表长等于容量时,新增加的元素将无法存储。此时有两种解决方法:一种是不执行插入,报告一个错误消息;另一种是扩大数组的容量,13,void insert(i,x)if(length=maxSize)resize();for(j=n-1;j=i;-j)dataj+1=dataj;datai=x;+length;,14,resize 操作的实现,resize操作按一定的比例扩大数组的空间,常用的比例是扩大一倍。数组空间在内存中必须是连续的,因此,扩大数组空间的操作必须重新申请一个更大规模的动态数组,将原
6、有数组的内容拷贝到新数组中,释放原有数组空间,将新数组作为存储线性表的存储区。,15,data,tmp,16,remove(i)运算的实现,void remove(i)for(j=i;j length-1;+j)dataj=dataj+1;-length;,17,顺序实现的算法分析,length,visit和clear的实现与表中的元素个数无关,因此它们的时间复杂度是O(1)。traverse()操作遍历整个表中的所有元素,因此时间复杂度为O(n)。create操作需要申请一块动态数组的空间,并设表为空。因此也是O(1)的时间复杂度。插入操作,需要移动结点。当i等于n时,移动次数为0。当i等于
7、0时,移动次数为n。最好情况下的时间复杂度为O(1)最坏情况下的时间复杂度为O(n)平均的时间复杂度:如果在每个位置上的插入都是等概率的,则插入算法的平均时间复杂度为n/2,18,线性表的顺序实现总结,由于要保持逻辑次序和物理次序的一致性,顺序表在插入删除时需要移动大量的数据,性能不太理想。由于逻辑次序和物理次序的一致性使得定位访问的性能很好。顺序表比较适合静态的、经常做定位访问的线性表。,19,表的实现,线性表的顺序实现线性表的链接实现,20,线性表的链接存储结构,将每个结点放在一个独立的存储单元中,结点间的逻辑关系依靠存储单元中附加的值针来给出。结点的存储单元在物理位置上可以相邻,也可以不
8、相邻。,21,线性表的链接存储,单链表双链表循环链表,22,单链表,每个结点附加了一个指针字段,如next,该指针指向它的直接后继结点,最后一个结点的next字段为空。,23,insert,p,24,头结点、头指针,为了消除特殊情况,通常在表头额外增加一个相同类型的特殊结点,称之为头结点。它们不是线性表中的组成部分。头结点的出现,使得在表头位置上进行插入和删除和在其它结点位置上是完全一致的,从而使得插入和删除算法得到简化。,25,带头结点的单链表,a0,a1,an-1,26,Create函数的实现,申请一块存储结点的空间,设结点的指针部分为空指针。将结点地址存入代表单链表的变量head。,27
9、,清除一个线性表clear(),把所有结点的空间还给系统,把头结点的指针部分置为空指针,void clear()p=头结点的直接后继;While(p!=空指针)q=p;p=p的直接后继地址;释放q的空间;头结点的后继指针置为空指针;,28,求表的长度length(),方法1:从起始结点开始,沿着后继指针链一个一个往后数,数到一个结点,长度加1,int length()len=0;p=头结点的直接后继;While(p!=空指针)+len;p=p的直接后继的地址;,方法2:用空间换取时间的方法。在保存单链表的时候增加一个变量,保存表的长度,29,在第i个位置插入一个元素insert(i,x),vo
10、id insert(i,x)for(j=0,p=head;j i;+j)p=p的直接后继的地址;tmp=new 结点;tmp指向的结点的数据部分=x;tmp指向的结点的指针部分=p的直接后继的地址;p指向的结点的指针部分=tmp;,30,删除第i个位置的元素remove(i),void remove(i)for(j=0,p=head;j i;+j)p=p的直接后继的地址;tmp=p的直接后继的地址;p的指针部分=tmp的直接后继的地址;delete tmp;,31,搜索某个元素在线性表中是否出现,int search(x)num=0;p=头结点的直接后继;while(p!=空指针,32,访问线
11、性表的第i个元素visit(i),dataType visit(i)for(j=0,p=head;j i;+j)p=p的直接后继的地址;return p指向的结点的数据部分;,33,遍历运算traverse(),void traverse()p=头结点的直接后继;While(p!=空指针)cout p指向结点的数据部分;p=p的直接后继的地址;,34,线性表的链接存储,单链表双链表循环链表,35,双链表,每个结点附加了两个指针字段,如prior和nextprior字段给出直接前驱结点的地址next给出直接后继结点的地址。,36,双链表的头尾节点,为了消除在表头、表尾插入删除的特殊情况,通常双链
12、表设一头结点,设一尾节点头结点中prior字段为空,它的next字段给出线性表中的首结点的地址尾结点中next字段为空,它的prior字段给出线性表中最后一个节点的地址,37,create运算,创建一个双链表就是创建一个只有头尾结点的链表,把头结点的地址保存在head中,尾结点的地址保存在tail中,38,insert,p,39,remove,x,p,40,线性表的链接存储,单链表双链表循环链表,41,单循环链表,一般单循环链表不带头结点,42,双循环链表,头结点中prior字段给出尾结点的地址,尾结点中next字段给出头结点的地址 一般也不设头尾结点,43,第二章 线性表,线性表的概念线性表
13、的实现线性表类的实现STL中线性表的实现,44,线性表类的实现,线性表抽象类顺序表类双链表类,45,线性表的抽象类,线性表的抽象类是一个类模板抽象类包括了除create运算以外的所有运算。create运算由每个线性表类的构造函数完成增加了一个虚析构函数,以防内存泄漏,46,线性表的抽象类,template class list public:virtual void clear()=0;virtual int length()const=0;virtual void insert(int i,const elemType,47,线性表类的实现,线性表抽象类顺序表类双链表类,48,顺序表类的定义
14、,class OutOfBound;class IllegalSize;template class seqList:public list private:elemType*data;int currentLength;int maxSize;void doubleSpace();,49,public:seqList(int initSize=10);seqList()delete data;void clear()currentLength=0;int length()const return currentLength;void insert(int i,const elemType,5
15、0,构造函数,template seqList:seqList(int initSize)if(initSize=0)throw IllegalSize();data=new elemTypeinitSize;maxSize=initSize;currentLength=0;,51,insert,template void seqList:insert(int i,const elemType,52,remove,template void seqList:remove(int i)if(i currentLength-1)throw OutOfBound();for(int j=i;j cu
16、rrentLength-1;j+)dataj=dataj+1;-currentLength;,53,doubleSpace,template void seqList:doubleSpace()elemType*tmp=data;maxSize*=2;data=new elemTypemaxSize;for(int i=0;i currentLength;+i)datai=tmpi;delete tmp;,54,其他函数,自己实现,55,线性表类的实现,线性表抽象类顺序表类双链表类,56,链表类的设计,以双链表为例链表类的数据成员:头指针、尾指针,以及为了提高时间性能而设置的数据成员curre
17、ntLength链表类必须实现线性表的所有操作。为保证这一点,链表类从线性表的抽象类继承。链表的插入、删除操作都需要将指针移到被操作结点。特设计函数move实现,57,结点及其组成,链表中的结点包含三部分:数据字段、前趋指针和后继指针字段。数据字段可以是任何类型的数据,这里仍然用ElemType表示;指针字段用于存放其他相关结点的地址值。由于结点类型是链表专用的,因此可设为内嵌类。由于链表的操作是通过对结点的操作实现的,于是把结点类定义成struct,以方便链表类访问。,58,双链表类的定义,template class linkList:public list private:struct
18、node elemType data;node*prev,*next;node(const elemType,59,public:linkList();linkList()clear();delete head;delete tail;void clear();int length()const return currentLength;void insert(int i,const elemType,60,构造函数,template linkList:linkList()head=new node;head-next=tail=new node;tail-prev=head;currentL
19、ength=0;,61,clear,template void linkList:clear()node*p=head-next,*q;head-next=tail;tail-prev=head;while(p!=tail)q=p-next;delete p;p=q;currentLength=0;,62,move,template linkList:node*linkList:move(int i)const node*p=head-next;if(i currentLength)throw OutOfBound();while(i-)p=p-next;return p;,63,templa
20、te void linkList:insert(int i,const elemType,insert,pos,64,remove,template void linkList:remove(int i)node*pos;pos=move(i);pos-prev-next=pos-next;pos-next-prev=pos-prev;delete pos;-currentLength;,65,search,template int linkList:search(const elemType,66,visit,template elemType linkList:visit(int i)co
21、nst node*p=move(i);return p-data;,67,traverse,template void linkList:traverse()constnode*p=head-next;cout data next;cout endl;,68,缺点,双链表类仅实现了线性表的基本运算,并没有用到双链表的特点,如逆向查找等,69,第二章 线性表,表的概念表的实现线性表类的实现STL中表的实现,70,STL,STL(标准模版库)是C+中数据结构的实现。这些数据结构被称为集合或容器。STL中线性表的实现有两种:vector:线性表的顺序实现list:线性表的双链表的实现,71,vect
22、or和list,共同支持的操作所有的容器都支持的整体操作:求规模、清空和判空在表尾的插入和删除以及取表头表尾元素list特有的操作:表头的插入和删除vector特有的操作:的重载,按下标取元素,求容量,重新设置数组的大小。迭代器:两者都能用迭代器访问,72,STL中的迭代器操作,获取一个迭代器:begin:返回一个指向第一个节点的迭代器end:返回一个指向最后一个节点的迭代器迭代器本身的方法:向后移动,取迭代器指向的元素值,判迭代器相等和不相等需要迭代器的容器操作:在指定位置上插入一元素删除指定位置的元素删除指定位置之间的所有元素,73,STL中线性表的实现,vector:线性表的顺序实现,且
23、大小可增长list:线性表的双链表实现,74,vector的特性,vector维护一个C+的原始数组、容量及大小规模提供拷贝构造函数和赋值运算符的重载函数,实现了对数组的整体操作可以修改数组的容量提供运算符重载提供了一个内嵌的迭代器头文件:vector,75,vector的定义,template class vector private:int theSize;int theCapacity;object*objects;public:enum SPARE_CAPACITY=16;,76,explicit vector(int initSize=0);vector(const Vector,不
24、允许隐式转换,77,bool empty()const;int size()const;int capacity()const;/对数据元素的操作 void push_back(const object/返回表尾元素的值,78,/迭代器操作typedef object*iterator;typedef const object*const_iterator;iterator begin();/返回元素0的地址const_iterator begin()const;/返回元素0的地址iterator end();/指向最后一个元素的地址const_iterator end()const;/指向最
25、后一个元素的地址;,79,vector的使用,#include#include using namespace std;int main()vector v;cout the initial size of v is:v.size()n the initial capacity of v is:v.capacity()endl;,80,v.push_back(2);cout n after push 2,capacity of v is:v.capacity()endl;v.push_back(3);cout n after pust 3,capacity of v is:“v.capacit
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 第一 部分
链接地址:https://www.31ppt.com/p-6296813.html