持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
2022计算机考研408—数据结构—线性表、栈、队列、数组 手把手教学考研大纲范围内的线性表、栈、队列、数组 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出
Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会
链表
链表和顺序表其实是差不多的
顺序表在访问下一个的时候是用下标访问
链表访问下一个只能通过结构体中的指针
插入,删除的时候不需要改变其他元素,只需要修改指定元素前后元素的指针即可
//此链表的index为序列号从1开始 !!!!不是下标
//此链表多处用到new ,建议大家删一个new调试一下,就能了解到new和不用new的区别了
#include "iostream"
#include "vector"
using namespace std;
typedef struct LNode { //LNode类型 包含一个int值和一个指针指向下一个地址
int data;
struct LNode *next;
} LNode, *LinkList;
bool ListInit(LinkList &L, int val) { //初始化链表,要给一个初始值当作链表头节点
L = new LNode;
L->next = NULL;
L->data = val;
return true;
}
bool ListInsertE(LinkList &L, int val) { //添加一个元素到链表尾端
LNode *headL = new LNode; //保存一下链表当前的位置
headL = L;
while (L->next) { //循环到L最后面,然后把当前值给L的下一个
L = L->next;
}
LNode *temp = new LNode; //new一个结点,如果不new可能会使用上一个temp结点
temp->data = val;
temp->next = NULL;
L->next = temp;
L = headL; //链表的头位置给L
}
bool ListInsert(LinkList &L, int index, int val) { //插入到链表的序列index(注意不是下标)位置
LNode *headL = new LNode; //保存头位置的上一个(headL的下一个是头位置)
headL->next = L; //这里不保存头位置, 防止添加第一个位置时,链表会添加到第二个位置
int j = 0;
while (headL && j < (index - 1)) { //找到第index个位置
j++;
headL = headL->next;
}
if (!headL || index < 1) {
return false;
}
LNode *temp = new LNode; //new一个结点,(不new可能会用到上一个结点)
temp->data = val;
temp->next = headL->next; //把headL的下一个结点给temp的下一个结点
headL->next = temp; //把temp给headL的下一个结点 现在temp的下一个就是原headL的下一个结点,相当于把temp插入到了里面
L = headL->next;
return true;
}
bool ListDelete(LinkList &L, int index) { //删除指定序列index的值
LNode *headL = new LNode;
LNode *tempL = new LNode;
tempL->next = L; //tempL的下一个是头节点(防止删除第一个结点出现问题)
headL = tempL; //保存头结点的上一个,就是tempL
int j = 0;
while (tempL && j < (index - 1)) { //找到序列index的结点
tempL = tempL->next;
j++;
}
if (!tempL) { //如果tempL为NULL,直接退出,没有要删除的结点
return false;
}
tempL->next = tempL->next->next; //tempL的下一个的下一个给下一个 相当于下一个会被直接盖住(删除了下一个 )
L = headL->next; //把头结点给L
}
bool ListGetElem(LinkList L, int index, int &val) { //找到知道序列index的值,传送给val
int j = 0;
while (L && j < (index - 1)) { //找到序列为index的值
L = L->next;
j++;
}
if (!L) { //如果L为空,直接退出,没有此节点
return false;
}
val = L->data;
return true;
}
int ListGetIndex(LinkList L, int val) { //通过值找到指定序列下标
int index = 1;
while (L->data != val) {
L = L->next;
index++;
}
if (!L) {
return 0;
}
return index;
}
void ListCreateH(LinkList &L, vector<int> num) { //前插法创建节点(num数组的值创建链表)
L = new LNode;
L->next = NULL;
for (int i = 0; i < num.size(); i++) {
LNode *p = new LNode;
p->data = num[i];
p->next = L->next; //每次把L的下一个给p的下一个
L->next = p; //然后把p给L的下一个 p的下一个是原来L的下一个
}
L = L->next; //L的下一个才是num数组创建的第一个值
}
void ListCreateE(LinkList &L, vector<int> num) { //前插法创建节点(num数组的值创建链表)
L = new LNode;
LNode *headL = new LNode;
headL = L;
L->next = NULL;
for (int i = 0; i < num.size(); i++) {
LNode *p = new LNode;
p->data = num[i];
p->next = NULL;
L->next = p; //当前指针p给L的下一个
L = p; //把p给L p的上一个就是原L
}
L = headL->next; //头结点的下一个才是num创建的第一个结点
}
void ListPrint(LinkList L) { //输出链表各个的值
while (L) {
cout << L->data << " ";
L = L->next;
}
cout << "\n";
}
int main() {
vector<int> num = {1,2,3,4,5};
LinkList temp;
// ListCreateE(temp, num);
// ListPrint(temp);
// ListCreateH(temp, num);
// ListPrint(temp);
ListInit(temp, 10); //创建List链表
ListInsertE(temp, 10); //尾端插入值
ListInsertE(temp, 10);
ListPrint(temp);
ListInsert(temp, 1, 20); //插入一个值 到序列index位置
ListPrint(temp);
ListDelete(temp, 3); //删除链表中序列index的值
ListPrint(temp);
int val;
ListGetElem(temp, 3, val); //通过序列index找到值,传给val
cout << val << "\n";
ListPrint(temp);
cout << ListGetIndex(temp, 2) << "\n"; //通过值找到序列index
}