DS博客作业02--线性表
0.PTA得分截图
1.本周学习总结
1.1 总结线性表内容
- 顺序表结构体定义
typedef int ElemType;
typedef struct
{
ElemType data[MaxSize]; //存放顺序表元素
int length ; //存放顺序表的长度
} List;
typedef List *SqList;
- 顺序表插入
void InsertSq(SqList& L, int x)
{
int i=0;
int j;
while (i < L->length && L->data[i] < x)
{
i++;
}
for (j = L->length; j > i; j--)
{
L->data[j] = L->data[j - 1];
}
L->data[i] = x;
L->length++;
}
- 顺序表删除
void DelNode(SqList& L, int min, int max)
{
int i;
int j=0;
int k;
k = L->length;
L->length = 0;
for (i = 0; i < k; i++)
{
if (L->data[i]<min||L->data[i]>max)
{
L->data[j] = L->data[i];
j++;
}
}
L->length = j;
}
- 链表结构体定义
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next; //指向后继结点
} LNode,*LinkList;
应注意申请内存空间时一定要用new+原结构体名称LNode,不可用指针!
- 头插法
void CreateListF(LinkList& L, int n)
{
L = new LNode;
L->next = NULL;
LinkList S;
for(int i=0;i<n;i++)
{
S = new LNode;
S->next = NULL;
cin >> S->data;
S->next = L->next;
L->next = S;
}
}
- 尾插法
void CreateListR(LinkList& L, int n)
{
L = new LNode;
L->next = NULL;
LinkList node;
LinkList tail;
int i;
tail = L;
for (i = 1; i <= n; i++)
{
node = new LNode;
cin >> node->data;
node->next = NULL;
tail->next = node;
tail = node;
}
}
注意使用尾插法时,数据呈倒序,且必须定义尾指针tailptr!
- 链表插入、删除
void ListInsert(LinkList& L, ElemType &e,int i)
{
int j=0;
LinkList P = L, s;
while (P&&j<i-1)
{
j++;
P = P->next;
}
if(p==NULL)return false;
s = new LNode;
s->data = e;
s->next = P->next;
P->next = s;
return true;
}
void ListDelete(LinkList& L, ElemType &e,int i)
{
int j=0;
LinkList P = L, s,q;
while (P&&j<i-1)
{
j++;
P = P->next;
}
if(p==NULL)return false;
q=p->next;
if(q==NULL)return false;
e=q->data;
P->next = q->next;
delete q;
}
- 有序单链表数据插入、删除
void ListInsert(LinkList& L, ElemType e)
{
int j;
LinkList P = L, s;
while (P&&e>=P->next->data)
{
P = P->next;
}
s = new LNode;
s->data = e;
s->next = P->next;
P->next = s;
}
void ListDelete(LinkList& L, ElemType e)
{
LinkList F = L,q;
while (F)
{
if (e == F->next->data)
{
q = F->next;
F->next = q->next;
delete q;
}
F = F->next;
}
}
- 有序表合并
void MergeList(LinkList& L1, LinkList L2)
{
LinkList p1, p2;
LinkList tail;
p1 =L1 ->next;
L1->next = NULL;
p2 = L2->next;
tail = L1;
while (p1 && p2)
{
if (p1->data < p2->data)
{
tail->next = p1;
tail = p1;
p1 = p1->next;
}
else if (p2->data < p1->data)
{
tail->next = p2;
tail = p2;
p2 = p2->next;
}
else
{
tail->next = p2;
tail = p2;
p1 = p1->next;
p2 = p2->next;
}
}
if (p1)
tail->next = p1;
if (p2)
tail->next = p2;
}
-
循环链表是一种链式存储结构,它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环,且无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活,即从任一结点出发都可访问到表中所有结点。
-
双链表是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
1.2.谈谈你对线性表的认识及学习体会
- 不得不说,链表相对于上学期的C语言来说,难度无疑是大大加深了,对于基础不牢固的我来说学起来较为吃力。
- 可线性表也有其独到之处,只要掌握指针域的位置,以及各节点的位置,寻找起来还是轻松的。
- 在做线性表的题目中,往往需要在草稿纸上模拟链表来对其操作,减小想象错误。
2.PTA实验作业
2.1顺序表删除重复元素
2.1.1代码截图
2.1.2本题PTA提交列表说明
- 一开始编译错误是由于if()中==少了一个。
- 后来部分正确是由于把问题想得复杂,使用了多层循环,导致数据崩溃,后面寻找同时遍历的方法解决了。
2.2链表分割
2.2.1代码截图
2.2.2本题PTA提交列表说明
- 此题一开始在VS上做的很艰难,因为虽然知道要创建新链表,却不知如何让其顺序不发生错乱,后来上课看到了林智凯同学的做法,才恍然大悟,一次不错的学习经历。
2.3区间删除数据
2.3.1代码截图
2.3.2本题PTA提交列表说明
- 这道题问题是出在了比较的部分,后来才发现需要用到两个变量的替换。
3.阅读代码
3.1 题目及解题代码
3.1.1 该题的设计思路
- 当用慢指针 slow 遍历列表时,让另一个指针 fast 的速度是它的两倍。当 fast 到达列表的末尾时,slow 必然位于中间。
3.1.2 该题的伪代码
- 这道题很好的运用了同时遍历的做法
while (fast != NULL && fast->next != NULL) {
slow = slow->next;// fast 的速度是它的两倍
fast = fast->next->next;
时间复杂度只为O(n),空间复杂度为O(1)
3.1.3 运行结果
代码不全无法运行。。。
3.2 K 个一组翻转链表
3.2.1 该题的设计思路
3.2.2 该题的伪代码
- 此题难度真的非常大。。。看了好久才看懂。。
3.2.3 运行结果
- 缺少题目代码,无法运行。。