线性结构的特点:
(1)存在唯一的一个被称做“第一个”的数据元素;
(2)存在唯一的一个被叫做“最后一个”的数据元素;
(3)除第一个之外,集合中的每个数据元素均只有一个前驱;
(4)除最后一个之外,集合中每个数据元素均只有一个后驱;

2.1线性表的类型定义

ADT List{数据对象:数据关系:基本操作:InitLisst(&L);DestroyList(&L);ClearList(&L);ListEmpty(L);ListLength(L);GetElem(L,i,&e);LocateElem(L,e,compare());PriorElem(L,cur_e,&pre_e);NextElem(L,cur_e,&next_e);ListInsert(&L,i,e);ListDelet(&L,i,e);ListTraverse(L,visit());
}ADT List
/*算法2.1两个线性表的合并*/
void union(List &La,List Lb)
{la_len=ListLength(La);lb_len=ListLength(Lb);for(i=1;i<lb_len;i++){GetElem(Lb,i,e);if(!LocateElem(La,e,equal))ListInsert(La,++La_len,e);}
}
/*算法2.2将两个非递减序列线性链表合并成非递减线性链表*/
void MergeList(List La,List Lb,List &Lc)
{InitList(Lc);i=j=1;k=0;La_len=ListLength(La);Lb_len=ListLength(Lb);while((i<=La.len)&&(j<=Lb_len)){GetElem(La,i,ai);GetElem(Lb,j,bj);if(ai<=bj){ListInsert(Lc,++k,ai);++i;}else{ListInsert(Lc,++k,bj);++j;}}while(i<=La_len){GetElem(La,i++,ai);ListInert(Lc,++k,ai);}while(j<=Lb_len){GetElem(Lb,j++,bi);ListInsert(Lc,++k,bj);}
}

2.3线性表的顺序表示和实现

/*线性表的动态分配顺序存储结构*/
#define LIST_INIT_SIZE  100
#define LISTINCREMENT   10
typedef struct
{ElemType *elem;//存储空间基址int length;int listsize;//当前分配存储容量
}SqList;
/*算法2.3顺序表的初始化*/
Status InitList_Sq(SqList &L)
{L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!L.elem)eixt(OVERFLOW); L.length=0;L.listsize=LIST_INIT_SIZE;return OK;
}

//算法2.4线性表的插入操作
Status ListInsert_Sq(SqList &L,int i,ElemType)
{if(i<1||i>L.length+1)return ERROR;if(L.length>=L.listsize){newbase=(ElemType *)realloc(L.elem,L.(listsize+LISTINREMENT)*sizeof(ElemType));if(!newbase)exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}q=&(L.elem[i-1]);for(p=&(L.elem[L.length-1]);p>=q;--p)*(p+1)=*p;*q=e;++L.length;return OK;
}
//算法2.5线性表的第i个元素删除操作
Status ListDelete_Sq(SqList &L,int i,ElemType &e)
{if((i<1||(i>L.length))return ERROR;p=&(L.elem[i-1]);e=*p;q=L.elem+L.length-1;for(++p;p<=q;++p)*(p-1)=*p;--L.Length;return OK;
}
int LocateElem_Sq(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
{//在顺序表L中查找第1个值与e满足compare()元素的位序//若找到,则返回其在L中的位序,否则返回0i=1;      //i的初始值为第一个元素的位序p=L.elem;  //p的初值为第1个元素的为序while(i<=L.length&&!(*compare)(*p++,e)) ++1;if(i<=L.length)  return i;else return 0;
}//LocateElem_Sq
void MergeList_Sq(SqList La,SqList Lb,SqList &Lc)
{//已知顺序线性表La和Lb的元素按非递减排序//归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列pa=La.elem;pb=Lb.elem;Lc.listsize=Lc.length=La.length+Lb.length;pc=Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));if(!Lc.elem)exit(OVERFLOW);pa_last=La.elem+La.length-1;pb_last=Lb.elem+Lb.length-1;while(pa<=pa_last&&pb<=pb_last){if(*pa<=*pb)  *pc++=*pa++;else *pc++=*pb++;}while(pa<=pa_last) *pc++=*pa++;    //插入La的剩余元素while(pb<=pb_last) *pc++=*pb++; //插入Lb的剩余元素
}

2.3线性链表的表示和实现


//线性链表的单链表存储结构
typedef struct LNode
{ElemType   data;struct LNode   *next;
}LNode,*LinkList;
//单链表是非随机存储的数据结构
//算法2.8
Status GetElem_L(LinkList L,int i,ElemType &e)
{//L为带头结点的单链表的头指针//当第i个元素存在时,其值赋给e并返回OK,否则返回falsep=L->next; j=1;//初始化,p指向第一个节点,j为计数器while(p&&j<i){p=p->next; ++j;}if(!p||j>j) return EROOR;//第i个元素不存在e=p->data;return OK;
}

/*除了函数的参数需要说明类型外,算法中使用的辅助变量可以不作变量说明
,必要时对其作用给予注释。一般而言,a,b,c,d,e等用作数据元素名,i,j,k,l,m,n
等用作整型变量名,p,q,r等用作指针变量名。当函数返回值为函数结果状态代码时,
函数定义为Status类型。为了便于描述,除了值调用方式外,增添了C++语言引用调用
的参数传递方式。在形参表中,以&打头的参数即为引用参数*/

//算法2.9
Status ListInsert_L(LinkList &L,int i,ElemType e)
{//在带头结点的单线性链表中第i个位置之前插入元素ep=L; j=0;while(p&&j<=i-1){p=p->next; ++j;//寻找第i-1个节点}if(!p||j>i-1)return ERROR;//i小于或者大于表长+1s=(LinkList)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return OK:
}

//算法2.10
Status ListDelete_L(LinkList &L,int i,ElemType &e)
{//在带头结点的但线性表L,中删除第i个元素,并由e返回其值p=L; j=0;while(p->next&&j<i-1){//寻找第i个结点,并令p指向其前驱p=p->next; ++j;}if(!(p->next)||j>i-1)return ERROR;//删除位置不合理q=p->next; p->next=q->next;  //删除并释放结点e=q->data; free(q);
}
//算法2.11
void CreateList_L(LinkList &L,int n)
{//逆位序输入n个元素的值,建立带表头结点的单线性链表LL=(LinkList)malloc(sizeof(LNode));L->next=NULL;    //先建立一个带头结点的单链表for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));//生成新结点scanf(&p->data);       //输入元素值p->next=L->next; L->next=p;   //插入到表头         }
}
//算法2.12
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{//已知单链表La和Lb的元素按非递减排序//归并La和Lb得到新的单链表表Lc,Lc的元素也按值非递减排列pa=La->next; pb=Lb->next;Lc=pc=La;while(pa&&pb){if(pa->data<=pb->data){pc->next=pa;pc=pa;pa=pa->next;}else{pc->next=pb;pc=pb;pb=pb->next;}}pc->next=pa?pa:pb;   //插入剩余段free(Lb);        //释放Lb的头结点
}

静态链表

//线性表的静态单链表存储结构
#define MAXSIZE 1000//链表的最大长度
typedef struct
{ElemType data;int cur;
}component,SLinkList[MAXSIZE];

//算法2.13
int LocateElem_SL(SLinkList S,ElemTpye e)
{//在静态单线性表L中查找第1个值为e的元素//若找到,则返回它在L中的位序,否则返回0i=S[0].cur;                         //i指示表中的第一个结点while(i&&S[i].data!e) i=S[i].cur; //在表中顺序查找return i;
}

/*【例2-3】运算(A-B)U(B-A)*/
//假设由终端输入集合元素,先建立表示集合A的静态链表S
//而后在输入集合B的元素的同时查找S表,若存在和B相同的元素
//则从S表中删除之,否则将此元素插入S表//算法2.14 静态单链表的初始化
void InitSpace_SL(SLinkList &space)
{//将一位数组space中各个分量链成一个备用链表,space[0].cur为头指针//"0"表示空指针for(i=0;i<MAXSIZE-1;i++) space[i].cur=i+1;space[MAXSIZE-1].cur=0;
}
//算法2.15 从备用链表中申请一个结点空间
int Malloc_SL(SLinkList &space)
{//若备用链表非空,则返回分配的结点的下标,否则返回0i=space[0].cur;if(space[0].cur) space[0].cur=space[i].cur;return i;
}
//算法2.16 将下标为k的空闲空间回收到备用链表
void Free_SL(SLinkList &space,int k)
{space[k].cur=space[0].cur; space[0].cur=k;
}
//算法2.17
void differnce(SLinkList &space,int k)
{//依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)U(B-A)//的静态链表,S为其头指针。假设备用空间足够大,space[0].cur为其头指针InitSpace_SL(space);  //初始化备用空间S=Malloc_SL(space);       //生成S的头结点r=S;                  //r指向S的当前最后结点scanf(m,n);                //输入集合A和集合B的元素个数for(j=1;j<=m;++j){i=Malloc_SL(space);//分配结点scanf(space[i].data);//输入A的元素值space[r].cur=i;r=1;  //插入到表尾}space[r].cur=0;        //尾点指针为空for(j=1;j<=n;j++){//依次输入B的元素值,若不在当前表中,则插入,否则删除scanf(b);p=S;k=space[S].cur;//k指向集合中第一个节点while(k!=space[k].cur&&space[k].data!b)//在当前表中查找{p=k;k=space[k].cur;}//whileif(k==space[r].cur)//当前表中不存在该元素,插入在r所在结点之后,且r的位置不变{i=Malloc_SL(space);space[i].data=b;space[i].cur=space[r].cur;space[r].cur=i;}//ifelse{               //该元素已在表中,删除它space[p].cur=space[k].cur;Free_SL(space,k);if(r==k) r=p;}//else}//for
}//difference

循环链表


双向链表

//线性表的双向链表存储结构
typedef struct DuLNode
{ElemType data;struct DuLNode *prior;struct DuLNode *next;
}DuLNode,*DuLinkList;

Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e)
{//删除带头结点的双链循环线性表L中第i个元素,i的合法值为1<=i<=表长if(!(p=GetElemP_DuL(L,i)))return ERROR;e=p->data;p->prior->next=p->next;p->next->prior=p->prior;free(p);return OK;
}//ListDelete_DuL

Status ListInsert_DuL(DuLinkList &L,int i,ElemType e)
{//在带头结点的双链循环线性表L中第i个位置之前插入元素e//i的合法值为1<<i<<表长+1if(!(p=GetElemP_DuL(L,i)))//在L中确定插入位置指针preturn ERROR;if(!(s=(DuLinkList)malloc(sizeof(DuLNode))))return ERROR;s->data=e;s->prior=p->prior; p->prior->next=s;s->next=p; p->prior=s;return OK;
}//ListInsert_DuL


由于链表在空间的合理利用上和插入、删除时不需移动等优点,
在很多场合下,它是线性表的首选存储结构。然而,它也存在着实现
某些基本操作,如求线性表的长度时不如顺序存储结构的缺点;
另一方面,由于在链表中,结点之间的关系用指针来表示,则数据元素在线性表中的“位序”概念已弱化,而被数据元素在线性表中的“位置”所代替。
为此,从实际应用出发角度重新定义线性表及其基本操作

带头结点的线性链表

//一个带头结点的线性链表类型定义如下
typedef struct LNode
{ElemType data;struct LNode *next;
}*Link,*Position;typedef struct     //链表类型
{Link head,tail;    //分别指向线性链表中的头结点和最后一个结点int len;      //指示线性表中数据元素的个数
}LinkList;
//算法2.21
Status ListInsert_L(LinkList &L,int i,ElemType e)
{//在带头结点的单链线性表L的第i个元素之前插入元素if(!LocatePos(L,i-1,h)) return ERROR;    //插入位置不合理if(!MakeNode(s,e)) return ERROR;       //结点存储分配失败InsFirst(h,s);//对于从第i个结点开始的链表,第i-1个结点是它的头结点return OK;
}//ListInsert_L
//算法2.21
Status MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc),int (*compare)(ElemType,ElemType))
{//已知单链线性表La和Lb的元素按非递减排列//归并La和Lb得到的新单链表Lc,Lc的元素值非递减排列if(!InitList(Lc)) return ERROR; //存储空间分配失败ha=GetHead(La); hb=GetHead(Lb);   //ha,hb分别指向La和Lb的头结点pa=NextPos(La,ha); pb=NextPos(Lb,hb);//pa和pb分别指向La和Lb中当前结点while(pa&&pb)                   //La和Lb均非空{a=GetcurElem(pa); b=GetCurElem(pb);//a和b为两表中当前比较元素if((*compare)(a,b)<=0){DeFirst(hb,q);Append(Lc,q);pa=Nextpos(La,ha);}else{DeFirst(hb,q);Append(Lc,q);pb=NextPos(Lb,hb);}}//whileif(pa) Append(Lc,pa);      //链接La中剩余结点else Append(Lc,pb);        //链接Lb中剩余结点FreeNode(ha); FreeNode(hb);//释放La和Lb的头结点return OK;
}//MergeList_L

2.4一元多项式的表示及相加

数据结构 第二章 线性表相关推荐

  1. 数据结构第二章-线性表(详细知识点总结)

    目录 第二章 线性表 2.1 线性表的定义和操作 2.1.1 线性表的定义 2.1.2 线性表的基本操作 2.2线性表的顺序表示 2.2.1 顺序表的定义 2.2.2 顺序表上基本操作的实现 2.3 ...

  2. C语言数据结构-第二章线性表-电大

    第二章线性表--内容简介 本章将进入线性结构的学习. 线性结构是最简单.最常用的一种数据结构. 本章将学习线性表的定义.顺序和链式两种存储方式及相应存储结构上的运算实现.通过典型示例训练,掌握线性表的 ...

  3. 王道408数据结构——第二章 线性表

    文章目录 一.线性表的定义和基本操作 线性表 顺序表 1.插入操作 2.删除操作 3.按值查找(顺序查找) 二.单链表 1. 头插法 2. 尾插法 3. 按序号查找 4. 按值查找 5. 插入结点 6 ...

  4. C++ 数据结构第二章 ----- 线性表

    文章目录 线性表 线性表的顺序存储 一.基本概念 二.基本操作 线性表的链式存储 一.基本概念 二.基本操作 三.双链表 (1) 双链表的插入操作 (2) 双链表的删除操作 四.循环链表 五.循环双链 ...

  5. 数据结构第二章线性表学习笔记

    1.    C++程序设计模板   (关于template的解释)[以下内容摘自百度] 函数声明格式 template <class(或typename) any(或任意符合规则的名称)> ...

  6. (王道408考研数据结构)第二章线性表-第三节5:顺序表和链表的比较

    文章目录 一:逻辑结构比较 二:存储结构比较 三:基本操作比较 (1)初始化操作 (2)销毁操作 (3)插入和删除 (4)查找 顺序表和链表的选取原则 一:逻辑结构比较 顺序表和链表都是线性表,都是线 ...

  7. (王道408考研数据结构)第二章线性表-第三节1:单链表的定义及其操作(插入和删除,建立之尾插和头插)

    文章目录 一:单链表相关 (1)单链表的定义 (2)头指针与头结点 二:单链表代码描述 三:单链表的初始化 四:单链表的插入 五:单链表的删除 六:单链表查找 (1)按位查找 (2)按值查找 七:单链 ...

  8. (王道408考研数据结构)第二章线性表-第二节1:顺序表的定义

    文章目录 一:顺序表实现 (1)静态分配 (2)动态分配 二:顺序表特点 顺序表:也叫做线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素 一:顺序表实现 (1)静态分配 静 ...

  9. (王道408考研数据结构)第二章线性表-第一节:线性表的定义和基本操作

    文章目录 一:线性表的定义 二:线性表的基本操作 一:线性表的定义 线性表(Linear List):零个或多个数据元素的有限序列 元素之间是有顺序的 若元素存在多个,则第一个元素无前驱,最后一个元素 ...

  10. PTA数据结构第二章线性表

    顺序表 1-8 对于顺序存储的长度为N的线性表,访问结点和增加结点的时间复杂度分别对应为O(1)和O(N). T F 1-10 对于顺序存储的长度为N的线性表,删除第一个元素和插入最后一个元素的时间复 ...

最新文章

  1. 数据库之字段数据类型
  2. Gitlab环境快速部署(RPM包方式安装)
  3. .NET小笔记之程序集
  4. javascript获取url参数的代码
  5. .NET平台功能最强大,性能最佳的JSON库
  6. 团队作业—预则立他山之石
  7. webmagic框架
  8. vbs教程(1):弹窗
  9. QT5.14.2 + MSVC2017_64 + MySQL5.7.29 数据库驱动编译及配置
  10. 【业务安全03】密码找回业务安全
  11. 腾讯音乐知识图谱搜索实践
  12. eclipse运行出现an error has occur.see the log file解决办法
  13. loadrunner mysql性能测试_运用Loadrunner测试Mysql数据库性能 TRON•极客
  14. 1到10的阶乘 java_1到10的阶乘相加java编程问题
  15. 在恋爱游戏里跟你实时聊天的“AI”,其实可能是一位抠脚大汉
  16. 常见的中间件以及什么是中间件
  17. 关于低功耗输电线路在线监测摄像头,你知道多少
  18. 机器学习02_吴恩达版学习笔记
  19. BAS/BRAS/RADIUS简介
  20. Java继承和多态——子类继承性

热门文章

  1. 【鱼眼镜头3】[鱼眼畸变模型]:除法模型(核密度估计径向失真校正方法)
  2. 企业级 SpringBoot 教程 (十三)springboot集成spring cache
  3. 陈彬 2019-1-17
  4. 开发工具总结(6)之Android Studio模板配置详解(提高开发效率必备技能)
  5. T-Sql 创建全文索引
  6. Spark Mllib里数据集如何取前M行(图文详解)
  7. 深入浅出AOP(一)
  8. 加密算法实现数据通讯
  9. Python套接字编程(1)——socket模块与套接字编程
  10. 前端相关书籍(转摘)