(1) 首先链表我上学期已有必定的基础,因此学起来没有太大的困难,可是解决问题时不够老道, 没有写出的代码时间复杂度不是太好,和老师举例的算法有明显差距,这方面还需多积累。 (2) 其次链表操做会涉及到指针,指针的用法又能够至关巧妙,让原本复杂的问题变简单, 可是用很差可能会留下各类小bug,难以查找,甚至崩溃。因此要多多领悟总结。
实如今顺序表中删除某个区间数据。须要实现下述的三个函数完成该功能。 实现函数: CreateSqList:建立有序表,连续输入n个正数存入有序表中。L表示顺序表指针,n表示输入数据个数。 InsertSq(SqList *&L,int x):顺序表L中插入数据x。 DispSqList:输出顺序表L中全部数据。数据间空格隔开,尾部不能有空格。
用new分配内存给L L->length赋值为n,n为输入数据长度 if (n小于等于最大值50) then { 输出“大于数组长度” } end if if (n等于0) then { 输出 "error" 而且退出 } else if (n大于0) then { for (i 从0开始循环到 L->length-1) { 输入数据到 L->data[i]中 } } else 若是n<0为不合法 { 输出 "小于0 error" } end if
定义变量flag记录插入位置 for (i 从 1 循环到 L->length=1 ) { if (L->data[0] 大于 x) then //插入头 { 把标记flag = 0意为插入头 退出循环 } else if ( L->data[L->length - 1] 小于 x) 说明要插入尾 { 把标记flag = L->length - 1意为插入尾 退出循环 } else if L->data[i] 大于x而且L->data[i - 1] 小于x then { 找到中间插入点赋给flag flag = i } end if } end for if (flag 等于 L->length - 1) then { L->data[L->length] = x //在尾部插入x } else { for (i = L->length to flag) { L->data[i] = L->data[i - 1] //后移 } end for L->data[flag] = x //插入x } end if 长度L->length加1
for (从i = 0 循环到 L->length) { 输出 L->data[i] if i 小于 L->length - 1 then //结尾无空格 { 输出空格 } }
2.1.3本题PTA提交列表说明
算法
本题要求实现顺序表的操做集。
(1) List MakeEmpty():建立并返回一个空的线性表;数组
List MakeEmpty() { 声明结构体指针q,用malloc分配内存; 给q->Last 赋值为 -1表示为空 返回 q; }
(2) Position Find( List L, ElementType X ):返回线性表中X的位置。若找不到则返回ERROR;
for循环遍历顺序表查找X的位置,找不到返回ERROR函数
Position Find(List L, ElementType X) { for (从0开始循环到顺序表最后L->Last) { if (若是L->Data[i] 等于 X) { 返回位置i; } } 若是找不到返回 ERROR; }
(3)bool Insert( List L, ElementType X, Position P ):将X插入在位置P并返回true。若空间已满,则打印“FULL”并返回false;若是参数P指向非法位置,则打印“ILLEGAL POSITION”并返回false;
先判断是否合法,而后for循环查找插入位置,而后把插入位置以后的元素后移,把元素插入学习
bool Insert(List L, ElementType X, Position P) { if (若是最后元素位置L->Last 等于最大位置MAXSIZE-1) { 输出( "FULL") 返回 false } if (若是P小于0或者大于最后元素位置) { 输出( "ILLEGAL POSITION"); 返回 false; } if (若是P 小于等于 元素最后位置L->Last)须要移动元素 { for (i从最后位置L->next+1的位置循环到p) { L->Data中的i-1位置的元素移到i位置 } 经过循环后移结束后把L->Data[P]赋值为X L->Last最后元素位置加一 } else 不须要移动 { 经过循环后移结束后把L->Data[P]赋值为X L->Last最后元素位置加一 } 返回true }
(4) bool Delete( List L, Position P ):将位置P的元素删除并返回true。若参数P指向非法位置,则打印“POSITION P EMPTY”(其中P是参数值)并返回false。设计
bool Delete(List L, Position P) { if (若是p不合法) { 输出("POSITION %d EMPTY",P); 返回 false; } for (从头遍历一遍顺序表) { if (若是目标P 不等于当前i) { 就把L->Data[j++]赋值为L->Data[i]重构顺序表 } } 最后顺序表的最后元素位置L->Last减一 返回 true }
Q1:使用了new,可是题目是gcc编译
Q2:在尾部删除时没有考虑到
Q3:输出不对等小问题指针
设计函数分别求两个一元多项式的乘积与和。code
结构体定义blog
typedef struct equation { 定义int类型系数 number; 定义int类型次方 power; 定义equation* 指针next; }EQU;//equation方程
(1) 建链表(比较简单不详细介绍)排序
void CreateList(EQU *&head,int &count) { 用new分配内存 用for循环不断输入 尾插法建链表 }
(2) 多项式加法
在循环中相同次方的系数相加或者不相等就把大的赋值到addresult中,直到两个链表遍历完毕索引
void EquationAdd(EQU* const &head1, EQU* const &head2,EQU* &addresult) { 用new分配内存,具体细节不表 声明EQU指针q1来代替head1, q2来代替head2,temp为临时,p来代替addresult for (若是q1或q2不为空) { 用new为temp分配内存 if (若是q1和q2都不为空) { if (若是q1->power 等于 q2->power)就合并 { 把temp->power 赋值为q1->power 把temp->number 赋值为 q1->number + q2->number q1和q2都等于下一个节点 } else把次方大的接到结果链表 { 而后该链表指针后移一个节点 } } else if(q1遍历结束) { 就把q2的赋给temp } else q2遍历结束 { 就把q1的赋给temp } 每次循环结束前把temp接到结果链表 } p->next = NULL }
(3) 多项式乘法
用两个嵌套for把两个链表相乘,结果保存在temp,而后调用插入函数
void EquationMultiply(EQU *const &head1, EQU *const &head2, EQU *&Multiplyresult) { 用new分配内存,具体细节不表 声明EQU指针temp做为临时指针, p指针来代替Multiplyresult 声明EQU指针q1来代替head1,q2来代替head2 if (q1或者q2为空) { 结束函数 } for (若是q1遍历还没结束) { for (从q2头循环到q2尾) { 把q1和q2相乘的结果保存到temp 调用插入函数InterList(Multiplyresult, temp) } } }
(4) 插入函数
结果链表是按次方从大到小排序,用for循环找到插入点插入,有次方等于的就合并
void InterList(EQU *&head,EQU *&temp) { 声明EQU指针q和p来代替被插入链表,p指在q的前一个节点 for (经过q遍历链表即q不为空继续循环) { 若是有次方相等就合并,没有就插入 } }
(5)输出函数
遍历链表输出,链表为空等输出相应提示(相对简单,不详述)
Q1:一开始没有合并同类项
Q2:没有去除零项
Q3:一开始没有用插入函数,致使代码复杂,小问题多,就写了插入函数
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,咱们使用整数 pos 来表示链表尾链接到链表中的位置(索引从 0 开始)。 若是 pos 是 -1,则在该链表中没有环。
经过使用具备 不一样速度 的快、慢两个指针遍历链表,慢指针每次移动一步,而快指针每次移动两步 ,若是列表中不存在环,最终快指针将会最早到达尾部,此时咱们能够返回 false,若是有环快指针就必定会追上慢指针。
算法经典,时间复杂度o(n),空间复杂度o(1),我发现不少经典算法都是利用了两个或多个指针对链表操做,取得了可观的时间复杂度。