# 1.本周学习总结

## 1.1 总结线性表内容

• 顺序表结构体定义
typedef int ElemType;
typedef struct
{
ElemType data[MaxSize];		//存放顺序表元素
int length ;         		//存放顺序表的长度
} List;

• 构建顺序表
void CreateList(SqList& L, int n)		//构建顺序表函数 ，n为顺序表长度
{
L = new List;
L->length = n;
for (int i = 0; i < n; i++)
{
cin >> L->data[i];
}
}

• 顺序表插入
void InsertSq(SqList& L, int x)		//顺序表插入函数，x为要插入的数据
{
int i, j;
if (L->data[0] > x)		//要插入的数据比顺序表第一项元素还小
{
for (j = L->length; j > 0; j--)
{
L->data[j] = L->data[j - 1];
}
L->length++;
L->data[0] = x;
}
for (i = 0; i < L->length - 1; i++)		//要插入的数据在顺序表第一项元素和最后一项元素之间
{
if (L->data[i] < x && L->data[i + 1] > x)
{

for (j = L->length; j > i+1;j--)
{
L->data[j] = L->data[j - 1];
}
L->length++;
L->data[i + 1] = x;
return;
}
}
if (L->data[L->length - 1] < x)		//要插入的数据比顺序表最后一项元素还大
{
L->data[L->length] = x;
L->length++;
return;
}
}

• 顺序表删除
for (i = 0; i < L->length; i++)
{
if (L->data[i] >= min && L->data[i] <= max)
{
for (j = i; j < L->length - 1; j++)
{
L->data[j] = L->data[j + 1];
}
L->length--;
i--;		//避免删除一项元素后，此元素的后一项元素会被跳过
}
}

• 链表结构体定义
typedef struct LNode  		//定义单链表结点类型
{
ElemType data;
struct LNode *next;		//指向后继结点

• 头插法建链表
void CreateListF(LinkList& L, int n)
{

L = new LNode;
L->next = NULL;
ElemType i;
for ( i = 0; i < n; i++)
{

pre = new LNode;
cin >> pre->data;
pre->next = L->next;
L->next = pre;
}
}

• 尾插法建链表
void CreateListR(LinkList& L, int n)
{
L = new LNode;
tail = L;
L->next=NULL;
for (int i = 0; i < n; i++)
{
p = new LNode;
cin >> p->data;
p->next = NULL;
tail->next = p;
tail = p;
}
}

• 有序单链表数据插入
void ListInsert(LinkList& L, ElemType e)
{
p = L->next;
while (p->next)
{
if (p->data <= e && p->next->data >= e)
{
ptr = new LNode;
ptr->next = NULL;
ptr->data = e;
ptr->next = p->next;		//头插法插入数据
p->next = ptr;
return;
}
p = p->next;
}
if (p->data <= e)		//数据插入到尾结点后
{
ptr = new LNode;
ptr->next = NULL;
ptr->data = e;
p->next = ptr;
}

• 有序单链表数据删除
void ListDelete(LinkList& L, ElemType e)
{
p = L;
int flag = 0;
if (p->next == NULL||p==NULL)		//判断空链表
{
return;
}
while (p->next)
{
if (p->next->data == e)
{
ptr = p->next;
p->next = p->next->next;
delete ptr;
flag = 1;
}
p = p->next;
if (p == NULL)
{
break;
}
}
if (flag == 0)
{
cout << e << "找不到！" << endl;
}
}

• 有序链表合并
void MergeList(LinkList& L1, LinkList L2)
{
while (ptr->next && L2->next)
{
if (ptr->next->data > L2->next->data)
{
p = new LNode;
p->data = L2->next->data;

p->next = ptr->next;
ptr->next = p;
L2 = L2->next;
}
else if (ptr->next->data == L2->next->data)
{
L2 = L2->next;
}
ptr=ptr->next;
}
if (ptr->next == NULL )
{
ptr->next = L2->next;
}
}

• 循环链表
• 定义：循环链表中最后一个结点的指针域指向头结点，整个链表形成一个环 。判断循环链表为空链表的条件是：头指针L->next==L。
• 循环单链表图片：
• 双链表
• 定义：双向链表也叫双链表，其每个数据结点都有两个指针，分别指向直接前驱结点和直接后继结点。从双链表中的任意一个结点开始，都可以访问其前驱结点和后继结点。
• 双链表图片：

## 1.2 对线性表的认识及学习体会：

• 自我感觉线性表中顺序表比链表更简单，因为里面有很多数组的知识，至于链表方面一定要弄清楚节点间的关系，单链表中尤其注意指针next的用法。先把基础打牢，如先学会尾插法，头插法建链表，再循序渐进，如学会有序链表的插入，删除，合并等。我最开始做题时就常常出现指针为空指针，非法访问地址，尾节点数据重复输出等问题。

# 2.PTA实验作业

## 2.1 题目1：7-1 两个有序序列的中位数

### 2.1.2本题PTA提交列表说明

• 部分正确（6）：新建顺序表L3时直接用赋值表达式，没法把顺序表L1的每项元素赋给L3。解决办法：运用一个循环，分别把顺序表L1的每项元素赋给顺序表L3。
• 部分正确（17）：-->用C语言知识构造数组时，对数组L3中的元素排序时这种情况有问题。解决办法：每次在选择排序时内层循环之前都把变量i的值赋给变量k。
• 编译错误：-->定义变量时大小写错误
• 部分正确（21）：

## 2.2 题目2：6-3 jmu-ds- 顺序表删除重复元素

### 2.2.2本题PTA提交列表说明

• 部分正确：-->题目并未说出顺序表长度为零时该输出什么，直接return 回去就行。

## 2.3 题目3：6-9 jmu-ds-有序链表合并

### 2.3.2本题PTA提交列表说明

• 部分正确：-->合并的链表头指针为链表L1的头指针，但在循环中缺少指针移动的语句，即此指针无法指向链表L1的下一节点。

# 3.阅读代码

## 3.1 21. 合并两个有序链表

• 解题代码：
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if (l1 == NULL) return l2;
if (l2 == NULL) return l1;

while(l1&&l2)
{
if (l1 -> val < l2 -> val)
{
l3 -> next =l1;
l1 = l1 -> next;
l3 = l3 -> next;
}
else
{
l3 -> next = l2;
l2 = l2 -> next;
l3 = l3 -> next;
}
}
l3 -> next = l1 ? l1 : l2;
}


### 3.1.2 该题的伪代码

定义新链表l3的头指针head
while(l1&&l2)
{
if(链表l1节点的数据更小）
{
l1节点作为l3的后继节点
l1,l3同时移动到下一节点
}
else
{
l2节点作为l3的后继节点
l2,l3同时移动到下一节点
}
}
end while



## 3.2 83. 删除排序链表中的重复元素

• 解题代码
 ListNode* deleteDuplicates(ListNode* head)
{
while(first&&second)
{
if(first->val!=second->val)
{
first->next=second;
first=second;
}
second=second->next;
}
first->next=second;
}


### 3.2.2 该题的伪代码

判断链表是否为空
while(头节点first和下一节点second）
{
若两节点数据不同，移动头节点first
移动节点second
}
end while