线性表
总述
代码是抽象的——所以我们学习数据结构时尽量自己把图给画出来,自己去模拟这个过程,才能加深印象。
线性链表的创建
这里我们采用while
循环创建链表,当输入某一个特定的值(-9999)时停止创建。
基本思路
- 首先创建三个node指针,一个指向头
head
,一个指向尾p
,一个作为开辟新结点的工具q
。 (代码第4行) - 记得将
head
初始化为空,然后让p = head
(注意,此时的head
和p
都没有“实体”结点,都指向NULL
)。 (代码第4, 5行) head
为空:正常地new
然后赋值,接着让p
指向head
; (代码第9~14行)head
不为空:new
一个新结点q
,对两个成员变量进行赋值。让p->link
指向q
,接着让p指向新的“尾巴”p = q
。 (代码第16~22行)- 返回
head
即可。 (代码第26行)
出现过的问题
- 创建的表的首结点会重复两次。原因就在于☆处,没有再次输入n,导致n的值被用于创建首结点和第二个结点。
需要注意的点
- 特殊情况:空表和只有一个结点。
代码
NODE* create_link()
{
int n;
NODE* head = NULL, * p, * q;
p = head;
cin >> n;
while (n != -9999)
{
if (head == NULL) {
head = new NODE;
head->data = n;
head->link = NULL;
p = head; //p只需要指向head即可
☆ cin >> n; //还是需要一个cin,不然n的值没法更新,第一个就会创建两次
}
else{
q = new NODE; //用q创建,然后p再指
q->data = n;
q->link = NULL;
p->link = q;
p = q;
cin >> n;
}
p->link = NULL;
}
return(head);
}
线性链表的插入
基本思路
- 首先确定位置的三种情况:0,中间,>链表长度。其中,后两种可以合成一种情况讨论。
- 对于插在头结点的情况,我们直接添加(详情查看代码)。
- 对于另外的情况,首先要让指针指到要插入的位置。然后进行插入。
需要注意的点
- 分类讨论,插在表头的特殊情况
- 传递的参数需要是引用。 有没有直接传递指针就可以改变的方法呢?
- (接上一行)有!返回类型设置为
NODE*
,然后head = insert_link(head)
就行了
代码
// NODE* insert_link(NODE *head)
void insert_link(NODE *head) {
int loc; //作用:记录要插入的位置
cout << "Where do you want to insert?\n";
cin >> loc;
loc -= 1; //在原来结点的前面插入
NODE* pos = head; //作用是指向要插入的位置
//insert
int num; //该结点的值
cout << "please input the number\n";
cin >> num;
NODE* q = new NODE; //开始创建新的结点
q->data = num;
if (loc == -1) {
//problem: 返回后一切不变,传递的不是指针吗?
q->link = head;
head = q; //为什么它不会改变?传递的是指针,必须要引用指针?
}
else {
//find the position
while (pos->link != NULL && loc) {
//为什么它不会触发等于NULL的条件?因为↓
pos = pos->link; //不可以直接用pos++
loc--;
}
q->link = pos->link;
pos->link = q;
}
//return head; 如果传回指针,就加这句。
}
线性链表的删除
删除链表中值为a
的 第一个/所有 结点。
基本思路
- 确定特殊情况:为空链表、删除的是头结点
- 对于一般情况,即删除的结点在中间。让2个指针指向被删除结点及其前面的结点,然后将前面的结点的link接到下下个结点上,再
delete
要删除的结点即可。 - 对于为空,直接返回传入的参数
head
即可。 - 对于头结点,先
用q
保存本结点的地址,然后直接让head
指向下一个结点,再删除原头结点即可。
需要注意的点
- 讨论好特殊情况即可
代码
void delete_link(NODE* head, int a) {
//此处只需要传入头结点即可
if (head == NULL) {
//链表为空时
cout << "链表为空!\n";
return ;
}
NODE* q = head;
if (q->data == a)