首页 第二章 线性表

第二章 线性表

举报
开通vip

第二章 线性表nullnull2.1 线性表的类型定义2.3 线性表链式表示和实现2.4 一元多项式的表示2.2 线性表顺序表示和实现 第二章 线性表null线性结构的基本特征为:1.集合中必存在唯一的一个“第一元素”;2.集合中必存在唯一的一个 “最后元素” ;3.除最后元素在外,均有 唯一的后继;4.除第一元素之外,均有 唯一的前驱。 线性结构 是 一个数据元素的有序(次序)集线性表是一种最简单的线性结构null2.1 线性表的类型定义null抽...

第二章 线性表
nullnull2.1 线性 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 的类型定义2.3 线性表链式表示和实现2.4 一元多项式的表示2.2 线性表顺序表示和实现 第二章 线性表null线性结构的基本特征为:1.集合中必存在唯一的一个“第一元素”;2.集合中必存在唯一的一个 “最后元素” ;3.除最后元素在外,均有 唯一的后继;4.除第一元素之外,均有 唯一的前驱。 线性结构 是 一个数据元素的有序(次序)集线性表是一种最简单的线性结构null2.1 线性表的类型定义null抽象数据类型线性表的定义如下:ADT List { 数据对象:D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } {称 n 为线性表的表长; 称 n=0 时的线性表为空表。}数据关系:R1={ |ai-1 ,ai∈D, i=2,...,n }{设线性表为 (a1,a2, . . . ,ai,. . . ,an), 称 i 为 ai 在线性表中的位序。} null 基本操作: 结构创建/构造型操作结构销毁型操作 观察/ 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 型操作 变换/加工型操作 } ADT Listnull InitList( &L ) 操作结果:构造一个空的线性表L。结构创建/构造操作null 结构销毁操作DestroyList( &L )初始条件: 操作结果:线性表 L 已存在。销毁线性表 L。nullListEmpty( L )ListLength( L )PriorElem( L, cur_e, &pre_e )NextElem( L, cur_e, &next_e ) GetElem( L, i, &e )LocateElem( L, e, compare( ) )ListTraverse(L, visit( ))观察/报告型操作:null ListEmpty( L ) 初始条件: 操作结果:线性表L已存在。若L为空表,则返回 TRUE,否则FALSE。(线性表判空)nullListLength( L )初始条件: 操作结果:线性表L已存在。 返回L中元素个数。(求线性表的长度)null PriorElem( L, cur_e, &pre_e ) 初始条件: 操作结果:线性表L已存在。若cur_e是L的元素,但不是第一个,则用pre_e 返回它的前驱,否则操作失败,pre_e无定义。(求数据元素的前驱)nullNextElem( L, cur_e, &next_e )初始条件: 操作结果:线性表L已存在。 若cur_e是L的元素,但不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。(求数据元素的后继)nullGetElem( L, i, &e ) 初始条件: 操作结果:线性表L已存在, 且 1≤i≤LengthList(L)。用 e 返回L中第 i 个元素的值。(求线性表中某个数据元素)nullLocateElem( L, e, compare( ) )初始条件: 操作结果:线性表L已存在,e为给定值, compare( )是元素判定函数。返回L中第1个与e满足关系 compare( )的元素的位序。 若这样的元素不存在, 则返回值为0。(定位函数)null ListTraverse(L, visit( ))初始条件: 操作结果:线性表L已存在, Visit() 为某个访问函数。依次对L的每个元素调用 函数visit( )。一旦visit( )失败,则操作失败。(遍历线性表)null加工/变换型操作 ClearList( &L )ListInsert( &L, i, e ) ListDelete(&L, i, &e) nullClearList( &L )初始条件: 操作结果:线性表L已存在。将L重置为空表。 (线性表置空)nullnull ListInsert( &L, i, e )初始条件: 操作结果:线性表L已存在, 且 1≤i≤LengthList(L)+1 。在L的第i个元素之前插入 新的元素e,L的长度增1。(插入数据元素)nullListDelete(&L, i, &e)初始条件: 操作结果:线性表L已存在且非空, 1≤i≤LengthList(L) 。删除L的第i个元素,并用e返回其值,L的长度减1。(删除数据元素)null利用上述定义的线性表 可以实现其它更复杂的操作例 2-1 例 2-2 null 假设:有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即:线性表中的数据元素即为集合中的成员。 现要求一个新的集合A=A∪B。例 2-1 上述问题可演绎为: 要求对线性表作如下操作: 扩大线性表 LA,将存在于线性表LB 中而不存在于线性表 LA 中的数据元素插入到线性表 LA 中去。null1.从线性表LB中依次察看每个数据元素;2.依值在线性表LA中进行查访; 3.若不存在,则插入之。GetElem(LB, i)→e LocateElem(LA, e, equal( )) ListInsert(LA, n+1, e) 操作步骤:null GetElem(Lb, i, e); // 取Lb中第i个数据元素赋给e if (!LocateElem(La, e, equal( )) ) ListInsert(La, ++La_len, e); // La中不存在和 e 相同的数据元素,则插入之void union(List &La, List Lb) { La_len = ListLength(La); // 求线性表的长度 Lb_len = ListLength(Lb); for (i = 1; i <= Lb_len; i++) {}} // union例算法 2-1null 已知一个非纯集合 B,试构造一个纯集合 A,使 A中只包含 B 中所有值各不相 同的数据元素。仍选用线性表表示集合。null集合 B集合 A从集合 B 取出物件放入集合 A 要求集合A中同样物件不能有两件以上因此,算法的策略应该和例2-1相同nullvoid union(List &La, List Lb) { La_len=ListLength(La); Lb_len=ListLength(Lb); } // union GetElem(Lb, i, e); // 取Lb中第 i 个数据元素赋给 e if (!LocateElem(La, e, equal( )) ) ListInsert(La, ++La_len, e); // La中不存在和 e 相同的数据元素,则插入之for (i = 1; i <= Lb_len; i++) { }InitList(La); // 构造(空的)线性表LA例算法 2-1null若线性表中的数据元素相互之间可以比较,并且数据元素在线性表中依值非递减或非递增有序排列,即 ai≥ai-1 或 ai≤ai-1(i = 2,3,…, n),则称该线性表为有序表(Ordered List)。试改变结构,以有序表表示集合。数据结构改变了, 解决问题的策略也相应要改变。nullvoid MergeList(List La, List Lb, List &Lc) { // 将非递减的有序表 La 和 Lb 归并为有序表 Lc } // merge_listwhile ((i <= La_len) && (j <= Lb_len)) { // La 和 Lb 均不空 } while (i<=La_len) // 若 La 不空 while (j<=Lb_len) // 若 Lb 不空InitList(Lc); // 构造空的线性表 Lc i = j = 1; k = 0; La_len = ListLength(La); Lb_len = ListLength(Lb);例算法 2-2例 2-2 null while ((i <= La_len) && (j <= Lb_len)) // La 和 Lb 均非空,i = j = 1, k = 0 GetElem(La, i, ai); // 取表La中第i个数据元素的值赋给ai GetElem(Lb, j, bj); if (ai <= bj) { // 将 ai 插入到 Lc 中 ListInsert(Lc, ++k, ai); ++i; } else { // 将 bj 插入到 Lc 中 ListInsert(Lc, ++k, bj); ++j; }null while (i <= La_len) { // 当La不空时 GetElem(La, i++, ai); ListInsert(Lc, ++k, ai); } // 插入 La 表中剩余元素 while (j <= Lb_len) { // 当Lb不空时 GetElem(Lb, j++, bj); ListInsert(Lc, ++k, bj); } // 插入 Lb 表中剩余元素nullvoid MergeList(List La,List Lb,List &Lc) // 算法2.2 { // 已知线性表La和Lb中的数据元素按值非递减排列。 // 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列(不改变表La和表Lb) int i=1,j=1,k=0; int La_len,Lb_len; ElemType ai,bj; InitList(Lc); // 创建空表Lc La_len=ListLength(La); // 求线性表La的长度 Lb_len=ListLength(Lb); // 求线性表Lb的长度 while(i<=La_len&&j<=Lb_len) // i、j分别指示表La和表Lb中的元素序号 { GetElem(La,i,ai); // 取表La中第i个数据元素的值赋给ai GetElem(Lb,j,bj); // 取表Lb中第j个数据元素的值赋给bj if(ai<=bj) // 表La的当前元素不大于表Lb的当前元素 { ListInsert(Lc,++k,ai); // 在表Lc的最后插入元素ai ++i; // i指示表La中的下一个元素 } else { ListInsert(Lc,++k,bj); // 在表Lc的最后插入元素bj ++j; // j指示表Lb中的下一个元素 } } // 以下两个while循环只会有一个被执行 while(i<=La_len) // 表La中还有元素未插入到表Lc { GetElem(La,i++,ai); // 取表La中第i个数据元素的值赋给ai,i指示表La中的下一个元素 ListInsert(Lc,++k,ai); // 在表Lc的最后插入元素ai } while(j<=Lb_len) // 表Lb中还有元素未插入到表Lc { GetElem(Lb,j++,bj); // 取表Lb中第j个数据元素的值赋给bj,j指示表Lb中的下一个元素 ListInsert(Lc,++k,bj); // 在表Lc的最后插入元素bj } }nullnull 用一组地址连续的存储单元 依次存放线性表中的数据元素 a1 a2 … ai-1 ai … an 线性表的起始地址 称作线性表的基地址 线性表的顺序表示:null基本特点: (1)占用的存储空间是连续的; (2) 各数据元素在存储空间中是按逻辑顺序依次存放的。线性表的顺序存储结构:线性表中第i个元素ai在计算机存储空间中的存储地址为 LOC(ai) = LOC(a1) + (i-1)×ll:一个数据元素所占存储量 LOC(a1):基地址线性表的顺序存储结构是一种随机存取的存储结构。null顺序表示的 C 语言描述typedef struct { } SqList; // 俗称 顺序表#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量 #define LISTINCREMENT 10 // 线性表存储空间的分配增量ElemType *elem; // 存储空间基址int length; // 当前长度int listsize; // 当前分配的存储容量 // (以sizeof(ElemType)为单位)动态一维数组表示null线性表的基本操作在顺序表中的实现InitList(&L) // 结构初始化LocateElem(L, e, compare()) // 查找ListInsert(&L, i, e) // 插入元素ListDelete(&L, i) // 删除元素nullStatus InitList_Sq( SqList& L ) { // 构造一个空的线性表 } // InitList_Sq算法时间复杂度:O(1)L.elem = (ElemType*) malloc (LIST_ INIT_SIZEsizeof (ElemType)); if (!L.elem) exit(OVERFLOW);L.length = 0; L.listsize = LIST_INIT_SIZE return OK;动态一维数组表示null例如:顺序表e =38i12341850可见,基本操作是: 将顺序表中的元素 逐个和给定值 e 相比较。null int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType)) { // 在顺序表中查询第一个满足判定条件的数据元素, // 若存在,则返回它的位序,否则返回 0 } // LocateElem_Sq O( ListLength(L) )算法的时间复杂度为:i = 1; // i 的初值为第 1 元素的位序 p = L.elem; // p 的初值为第 1 元素的存储位置while (i <= L.length && !(*compare)(*p++, e)) ++i;if (i <= L.length) return i; else return 0;(*compare)(*p++, e)null线性表操作 ListInsert(&L, i, e)的实现:首先分析:插入元素时, 线性表的逻辑结构发生什么变化? null (a1, …, ai-1, ai, …, an) 改变为 (a1, …, ai-1, e, ai, …, an), null Status ListInsert_Sq(SqList &L, int i, ElemType e) { // 在顺序表L的第 i 个元素之前插入新的元素e, // i 的合法范围为 1≤i≤L.length+1 } // ListInsert_Sq 算法时间复杂度为:O( ListLength(L) )q = &(L.elem[i-1]); // q 指示插入位置 for (p = &(L.elem[L.length-1]); p >= q; --p) *(p+1) = *p; // 插入位置及之后的元素右移 *q = e; // 插入e ++L.length; // 表长增1 return OK;……元素右移null考虑移动元素的平均情况: 若假定在线性表中任何一个位置上进行插入的概率都是相等的,则移动元素的期望值为:nullif (L.length >= L.listsize) { // 当前存储空间已满,增加分配 newbase = (ElemType *)realloc(L.elem, (L.listsize+LISTINCREMENT)*sizeof (ElemType)); if (!newbase) exit(OVERFLOW); // 存储分配失败 L.elem = newbase; // 新基址 L.listsize += LISTINCREMENT; // 增加存储容量 }if (i < 1 || i > L.length+1) return ERROR; // 插入位置不合法null例如:ListInsert_Sq(L, 5, 66) L.length-1087564266q = &(L.elem[i-1]); // q 指示插入位置 for (p = &(L.elem[L.length-1]); p >= q; --p) *(p+1) = *p;null线性表操作 ListDelete(&L, i, &e)的实现:首先分析:删除元素时, 线性表的逻辑结构发生什么变化?null (a1, …, ai-1, ai, ai+1, …, an) 改变为 (a1, …, ai-1, ai+1, …, an)ai+1…an, 表的长度减少nullStatus ListDelete_Sq (SqList &L, int i, ElemType &e) { } // ListDelete_Sqfor (++p; p <= q; ++p) *(p-1) = *p; // 被删除元素之后的元素左移 --L.length; // 表长减1 return OK;算法时间复杂度为: O( ListLength(L))p = &(L.elem[i-1]); // p 为被删除元素的位置 e = *p; // 被删除元素的值赋给 e q = L.elem+L.length-1; // 表尾元素的位置if ((i < 1) || (i > L.length)) return ERROR; // 删除位置不合法元素左移null考虑移动元素的平均情况:若假定在线性表中任何一个位置上进行删除的概率都是相等的,则移动元素的期望值为:nullL.length-108756p = &(L.elem[i-1]); q = L.elem+L.length-1; for (++p; p <= q; ++p) *(p-1) = *p; 例如:ListDelete_Sq(L, 5, e) nullnull一、单链表二、结点和单链表的 C 语言描述三、线性表的操作在单链表中的实现四、一个带头结点的单链表类型五、静态链表思考:线性表的逻辑顺序与存储顺序 ?一致的。六、其它形式的链表null 用一组地址任意的存储单元存放线性表中的数据元素。一、单链表以元素(数据元素的映象) + 指针(指示后继元素存储位置) = 结点 (表示数据元素 或 数据元素的映象)以“结点的序列”表示线性表  称作链表单链表的结点结构null头结点头指针头指针 有时为了操作方便,在第一个结点之前虚加一个“头结点”,以指向头结点的指针为链表的头指针。空指针线性表为空表时, 头结点的指针域为空null Typedef struct LNode // 结点类型定义  { ElemType data; // 数据域 struct Lnode *next; // 指针域 } LNode, *LinkList; //LinkList为结构指针类型二、结点和单链表的 C 语言描述LinkList L; // L 为单链表的头指针null三、单链表操作的实现GetElem(L, i, e) // 取第i个数据元素ListInsert(&L, i, e) // 插入数据元素ListDelete(&L, i, e) // 删除数据元素ClearList(&L) // 重置线性表为空表CreateList(&L, n) // 生成含 n 个数据元素的链表InitList(LinkList &L) //构造一个空的线性表Lnull 线性表的操作 GetElem(L, i, &e) 在单链表中的实现:j123null 因此,查找第 i 个数据元素的基本操作为:移动指针,比较 j 和 I 。 单链表是一种顺序存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。 令指针 p 始终指向线性表中第 j 个数据元素。null Status GetElem_L(LinkList L, int i, ElemType &e) { // L是带头结点的链表的头指针,以 e 返回第 i 个元素 } // GetElem_L算法时间复杂度为:O(ListLength(L))p = L->next; j = 1; // p指向第一个结点,j为计数器while (p && jnext; ++j; } // 顺指针向后查找,直到 p 指向第 i 个元素 // 或 p 为空if ( !p || j>i ) return ERROR; // 第 i 个元素不存在 e = p->data; // 取得第 i 个元素 return OK;null 线性表的操作 ListInsert(&L, i, e) 在单链表中的实现: 有序对 改变为 null 因此,在单链表中第 i 个结点之前进行插入的基本操作为: 找到线性表中第i-1个结点,然后修改其指向后继的指针。 可见,在链表中插入结点只需要修改指针。但同时,若要在第 i 个结点之前插入元素,修改的是第 i-1 个结点的指针。null Status ListInsert_L(LinkList L, int i, ElemType e) { // L 为带头结点的单链表的头指针,本算法 // 在链表中第i 个结点之前插入新的元素 e } // LinstInsert_L算法的时间复杂度为:O(ListLength(L))……p = L; j = 0; while (p && j < i-1) { p = p->next; ++j; } // 寻找第 i-1 个结点 if (!p || j > i-1) return ERROR; // i 大于表长或者小于1 nulls = (LinkList) malloc ( sizeof (LNode)); // 生成新结点 s->data = e; s->next = p->next; p->next = s; // 插入 return OK;spnull线性表的操作ListDelete (&L, i, &e)在链表中的实现:有序对 改变为 null 在单链表中删除第 i 个结点的基本操作为:找到线性表中第i-1个结点,修改其指向后继的指针。q = p->next; p->next = q->next; e = q->data; free(q);pqnull Status ListDelete_L(LinkList L, int i, ElemType &e) { // 删除以 L 为头指针(带头结点)的单链表中第 i 个结点 } // ListDelete_L算法的时间复杂度为:O(ListLength(L))p = L; j = 0; while (p->next && j < i-1) { p = p->next; ++j; } // 寻找第 i 个结点,并令 p 指向其前趋 if (!(p->next) || j > i-1) return ERROR; // 删除位置不合理q = p->next; p->next = q->next; // 删除并释放结点 e = q->data; free(q); return OK;null操作 ClearList(&L) 在链表中的实现:void ClearList(&L) { // 将单链表重新置为一个空表 while (L->next) { p=L->next; L->next=p->next; } } // ClearListfree(p);算法时间复杂度:O(ListLength(L))null如何从线性表得到单链表?链表是一个动态的结构,它不需要予分配空间,因此生成链表的过程是一个结点“逐个插入” 的过程。null例如:逆位序输入 n 个数据元素的值, 建立带头结点的单链表。操作步骤:一、建立一个“空表”;二、输入数据元素an, 建立结点并插入;三、输入数据元素an-1, 建立结点并插入;ananan-1四、依次类推,直至输入a1为止。nullvoid CreateList_L(LinkList &L, int n) { // 逆序输入 n 个数据元素,建立带头结点的单链表 } // CreateList_L算法的时间复杂度为:O(Listlength(L))L = (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; // 插入 }思考:不带头结点的单链表如何操作?InitList_L(L) // 先建立一个带头结点的单链表null void MergeList(LinkList La,LinkList &Lb,LinkList &Lc) // 算法2.12 { // 已知单链线性表La和Lb的元素按值非递减排列。 // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。(销毁Lb,Lc即新的La) LinkList pa=La->next,pb=Lb->next,pc; // pa、pb分别指向La、Lb的首元结点(待比较结点) Lc=pc=La; // 用La的头结点作为Lc的头结点,pc指向La的头结点(Lc的尾结点) while(pa&&pb) // La和Lb中的元素都未比较完 if(pa->data<=pb->data) // La的当前元素不大于Lb的当前元素 { pc->next=pa; // 将pa所指结点归并到Lc中 pc=pa; // pc指向表Lc的最后一个结点 pa=pa->next; }// 表La的下一个结点成为待比较结点 else // Lb的当前元素小于La的当前元素 { pc->next=pb; // 将pb所指结点归并到Lc中 pc=pb; // pc指向表Lc的最后一个结点 pb=pb->next; } // 表Lb的下一个结点成为待比较结点 pc->next=pa?pa:pb; // 插入剩余段 free(Lb); // 释放Lb的头结点 Lb=NULL; // Lb不再指向任何结点 }算法2.12与算法2.7比较null回顾 2.1 节中例子的算法,看一下当线性表分别以顺序存储结构和链表存储结构实现时,它们的时间复杂度为多少?nullvoid 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); }//for } // union控制结构: 基本操作:for 循环 GetElem, LocateElem 和 ListInsert当以顺序映像实现抽象数据类型线性表时为: O( ListLength(La)×ListLength(Lb) ) 当以链式映像实现抽象数据类型线性表时为: O( ListLength(La)×ListLength(Lb) )例2-1算法时间复杂度null用上述定义的单链表实现线性表的操作时, 存在的问题: 改进链表的设置:1.单链表的表长是一个隐含的值; 1.增加“表长”、“表尾指针” 和 “当前位置的 指针” 三个数据域;2.在单链表的最后一个元素之后插入元素时, 需遍历整个链表;3.在链表中,元素的“位序”概念淡化,结点的 “位置”概念加强。2.将基本操作中的“位序 i ”改变为“指针 p ”。null四、一个带头结点的线性链表类型typedef struct LNode { // 结点类型 ElemType data; struct LNode *next; } *Link, *Position;typedef struct { // 链表类型 Link head, tail; // 分别指向头结点和 // 最后一个结点的指针 int len; // 指示链表长度 Link current; // 指向当前被访问的结点 //的指针,初始位置指向头结点 } LinkList; (p37)nullnull链表的基本操作:(p37){结构初始化和销毁结构}Status InitList( LinkList &L ); // 构造一个空的线性链表 L,其头指针、 // 尾指针和当前指针均指向头结点, // 表长为零。Status DestroyList( LinkList &L ); // 销毁线性链表 L,L不再存在。 O(1) O(n)Status MakeNode( Link &p, ElemType e ); // 分配由 p 指向的值为e的结点,并返回OK, // 若分配失败,则返回 ERRORvoid FreeNode( Link &p ); // 释放 p 所指结点 O(1) O(1)null{报告/观察型操作}Status ListEmpty ( LinkList L ); //判表空int ListLength( LinkList L ); // 求表长Status Prior( LinkList L ); // 改变当前指针指向其前驱Status Next ( LinkList L ); // 改变当前指针指向其后继ElemType GetCurElem ( LinkList L ); // 返回当前指针所指数据元素O(1)O(1)O(n)O(1)O(1)null Status LocatePos( LinkList L, int i ); // 改变当前指针指向第i个结点Status LocateElem (LinkList L, ElemType e, Status (*compare)(ElemType, ElemType)); // 若存在与e 满足函数compare( )判定关系的元 // 素,则移动当前指针指向第1个满足条件的 // 元素的前驱,并返回OK; 否则返回ERRORStatus ListTraverse(LinkList L, Status(*visit)() ); // 依次对L的每个元素调用函数visit()O(n)O(n)O(n)null {变换/加工型操作}Status ClearList ( LinkList &L ); // 重置 L 为空表Status SetCurElem(LinkList &L, ElemType e ); // 更新当前指针所指数据元素Status Append ( LinkList &L, Link s ); // 在表尾结点之后链接一串结点Status InsAfter ( LinkList &L, Elemtype e ); // 将元素 e 插入在当前指针之后Status DelAfter ( LinkList &L, ElemType& e ); // 删除当前指针之后的结点 O(1)O(n) O(s) O(1) O(1)nullStatus InsAfter( LinkList& L, ElemType e ) { // 若当前指针在链表中,则将数据元素e插入在线性链 // 表L中当前指针所指结点之后,并返回OK; // 否则返回ERROR。 } // InsAfter if ( ! L.current ) return ERROR; if (! MakeNode( s, e) ) return ERROR; s->next = L.current->next; L.current->next = s; if (L.tail = L.current) L.tail = s; L.current = s; return OK;nullStatus DelAfter( LinkList& L, ElemType& e ) { // 若当前指针及其后继在链表中,则删除线性链表L中当前 // 指针所指结点之后的结点,并返回OK; 否则返回ERROR。 } //DelAfterif ( !(L.current && L.current->next ) ) return ERROR; q = L.current->next; L.current->next = q->next; if (L.tail = q) L.tail = L.current; e=q->data; FreeNode(q); return OK;null 1. 双向链表五、其它形式的链表typedef struct DuLNode { ElemType data; // 数据域 struct DuLNode *prior; // 指向前驱的指针域 struct DuLNode *next; // 指向后继的指针域 } DuLNode, *DuLinkList;null 最后一个结点的指针域的指针又指回第一个结点的链表 a1 a2 … ... an 2. 循环链表 和单链表的差别仅在于,判别链表中最后一个结点的条件不再是“后继是否为空”,而是“后继是否为头结点”。null双向循环链表空表非空表 a1 a2 … ... an null双向链表的操作特点:“查询” 和单链表相同。“插入” 和“删除”时需要同时修改两个方向上的指针。nulls->next = p->next; p->next = s; s->next->prior = s; s->prior = p;ps插入null删除p->next = p->next->next; p->next->prior = p;pnullnull在计算机中,可以用一个线性表来表示: P = (p0, p1, …,pn)一元多项式但是对于形如 S(x) = 1 + 3x10000 – 2x20000 的多项式,上述表示 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 是否合适?null 一般情况下的一元稀疏多项式可写成 Pn(x) = p1xe1 + p2xe2 + ┄ + pmxem 其中:pi 是指数为ei 的项的非零系数, 0≤ e1 < e2 < ┄ < em = n可以下列线性表表示: ((p1, e1), (p2, e2), ┄, (pm,em) )nullADT Polynomial { 数据对象: 数据关系:抽象数据类型一元多项式的定义如下:D={ ai | ai ∈TermSet, i=1,2,...,m, m≥0 TermSet 中的每个元素包含一个 表示系数的实数和表示指数的整数 }R1={ |ai-1 ,ai∈D, i=2,...,n 且ai-1中的指数值<ai中的指数值 }null CreatPolyn ( &P, m ) DestroyPolyn ( &P ) PrintPolyn ( &P ) 基本操作:操作结果:输入 m 项的系数和指数, 建立一元多项式 P。初始条件:一元多项式 P 已存在。 操作结果:销毁一元多项式 P。初始条件:一元多项式 P 已存在。 操作结果:打印输出一元多项式 P。null PolynLength( P ) AddPolyn ( &Pa, &Pb ) SubtractPolyn ( &Pa, &Pb ) … … } ADT Polynomial初始条件:一元多项式 P 已存在。 操作结果:返回一元多项式 P 中的项数。初始条件:一元多项式 Pa 和 Pb 已存在。 操作结果:完成多项式相加运算,即: Pa = Pa+Pb,并销毁一元多项式 Pb。null一元多项式的实现:typedef struct { // 项的表示 float coef; // 系数 int expn; // 指数 } term, ElemType; typedef OrderedLinkList polynomial; // 用带表头结点的有序链表表示多项式结点的数据元素类型定义为:null例如:多项式的单链表表示法 A(x)=7+3x+9x8+5x17 B(x)=8x+22x7-9x8多项式相加得到的多项式和 nullStatus CreatPolyn ( polynomail &P, int m ) { // 输入m项的系数和指数,建立表示一元多项式的有序链表P } // CreatPolynInitList (P); e.coef = 0.0; e.expn = -1; SetCurElem (h, e); // 设置头结点的数据元素for ( i=1; i<=m; ++i ) { // 依次输入 m 个非零项 } return OK;scanf (e.coef, e.expn); if (!LocateElem ( P, e, (*cmp)()) ) if ( !InsAfter ( P, e ) ) return ERROR; 注意: 1.输入次序不限; 2.指数相同的项只能输入一次。nullStatus AddPolyn ( polynomial &Pc, polynomial &Pa, polynomial &Pb) { // 利用两个多项式的结点构成“和多项式” Pc = Pa+Pb … … if (DelAfter(Pa, e1)) a=e1.expn else a=MAXE; if (DelAfter(Pb, e2)) b=e2.expn else b=MAXE; while (!(a=MAXE && b=MAXE)) { … … } … … } // AddPolynnullswitch (*cmp(e1, e2)) { case -1: { // 多项式PA中当前结点的指数值小 … … break; } case 0: { // 两者的指数值相等 e1.coef= a.coef + b.coef ; if ( a.coef != 0.0 ) InsAfter(Pc, e1); … … break; } case 1: { //多项式PB中当前结点的指数值小 … … break; } } null // func2-2.cpp 几个常用的函数 Status equal(ElemType c1,ElemType c2) { // 判断是否相等的函数 if(c1==c2) return TRUE; else return FALSE; } int comp(ElemType a,ElemType b) { // 根据a<、=或>b,分别返回-1、0或1 if(a==b) return 0; else return (a-b)/abs(a-b); }null 顺序存储结构可以借助于高级程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 语言中的一堆数组来表示,一维数组的下标与元素在线性表中的序号相对应。线性表的顺序存储结构可用C语言定义如下: #define MAXSIZE=线性表可能达到的最大长度 typedef struct {  ElemType elem[MAXSIZE]; /* 线性表占用的数组空间 */ int last; /* 记录线性表中最后一个元素在数组elem[ ]中 的位置(下标值), 空表置为-1 */ } SeqList; 线性表顺序存储结构(静态一维数组)表示null调用InitList (L)void InitList(LinkList &L) { // 操作结果:构造一个空的线性表L L=(LinkList)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点 if(!L) // 存储分配失败 exit(OVERFLOW); L->next=NULL; // 头结点的指针域为空 }构造一个空的线性表Lnull void MergeList(LinkList La,LinkList &Lb,LinkList &Lc) // 算法2.12 { // 已知单链线性表La和Lb的元素按值非递减排列。 // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。(销毁Lb,Lc即新的La) LinkList pa=La->next,pb=Lb->next,pc; // pa、pb分别指向La、Lb的首元结点(待比较结点) Lc=pc=La; // 用La的头结点作为Lc的头结点,pc指向La的头结点(Lc的尾结点) while(pa&&pb) // La和Lb中的元素都未比较完 if(pa->data<=pb->data) // La的当前元素不大于Lb的当前元素 { pc->next=pa; // 将pa所指结点归并到Lc中 pc=pa; // pc指向表Lc的最后一个结点 pa=pa->next; }// 表La的下一个结点成为待比较结点 else // Lb的当前元素小于La的当前元素 { pc->next=pb; /
本文档为【第二章 线性表】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_608069
暂无简介~
格式:ppt
大小:1MB
软件:PowerPoint
页数:0
分类:互联网
上传时间:2011-05-13
浏览量:21