1. 指针的引用
1.没有引用
2. 添加引用
- 实参和形参都是指针变量时,指向的地址空间是可以相互看见的。
黄金重点,至高理解
4. 指针变量添加引用
2. 在顺序表的第i个位置,插入一个元素
#include <bits/stdc++.h>
using namespace std;
#define Max 50
/*
线性表第i个位置插入元素e
*/
typedef struct sqlist
{
int a[Max] = {1, 25, 77, 8, 99};
int length = 5;
} sqlist;
bool insertSqlist(sqlist &L, int n, int e)
{
if (n < 0 || n > L.length + 1) // 插入位置,小于0,或者大于表的长度
return false;
if (n >= Max)
return false; // 空间已满不能插入
for (int i = L.length; i >= n; i--)
L.a[i] = L.a[i - 1]; //将后面的往后移
L.a[n - 1] = e;
L.length++;
};
void printList(sqlist L)
{
for (int i = 0; i < L.length; i++)
cout << L.a[i] << ' ';
};
int main()
{
sqlist L;
insertSqlist(L, 4, 999);
printList(L);
return 0;
}
3. 在顺序表中删除第i个元素
#include <bits/stdc++.h>
using namespace std;
#define Max 50
/*
删除顺序表第i个元素
*/
struct sqlist
{
int data[Max] = {1, 4, 56, 75, 76, 5};
int length = 6;
};
bool deleteList(sqlist &list, int n, int &e)
{
if (n < 0 || n > list.length + 1)
return false;
e = list.data[n-1];
for (int i = n; i < list.length; i++)
{
list.data[i-1] = list.data[i ];
}
list.length--;
return true;
};
void printList(sqlist L)
{
for (int i = 0; i < L.length; i++)
cout << L.data[i] << ' ';
};
int main()
{
sqlist list;
int e;
deleteList(list, 4, e);
printList(list);
return 0;
}
4. 头插法建立单链表,有头节点
#include <bits/stdc++.h>
using namespace std;
#define Max 50
/**
*头插法建立单链表,有头节点
*
*/
typedef struct LNode
{
int data; // 数据域
struct LNode *next; // 指针域,指向后继
} LNode, *linklist;
int a[4] = {1, 2, 3, 4};
int n = 4;
void createList(linklist &L)
{
LNode *s;
L = (linklist)malloc(sizeof(LNode));
L->data = 0;
L->next = NULL; // 创建头结点,初始化为空表
for (int i = 0; i < n; i++)
{
s = (linklist)malloc(sizeof(LNode));
s->data = a[i];
// 插入s到表头
s->next = L->next;
L->next = s;
}
};
void disp(LNode *L)
{
LNode *s = L;
s = s->next;
while (s)
{
cout << s->data << ' ';
s = s->next;
}
}
int main()
{
LNode *L;
createList(L);
disp(L);
return 0;
}
//
5. 头插法建立单链表 ,无头结点
#include <bits/stdc++.h>
using namespace std;
#define Max 50
/**
*头插法建立单链表,无头节点
*
*/
typedef struct LNode
{
int data; // 数据域
struct LNode *next; // 指针域,指向后继
} LNode, *linklist;
int a[4] = {1, 2, 3, 4};
int n = 4;
void createList(linklist &L)
{
LNode *s;
// 最初状态下,头指针 H 没有任何结点,所以,插入第一个元素,就相当于是创建结点 H
L = (linklist)malloc(sizeof(LNode));
L->data = a[0];
L->next = NULL;
for (int i = 1; i < n; i++)
{
s = (linklist)malloc(sizeof(LNode));
s->data = a[i];
s->next = L;
L = s;
}
};
void disp(LNode *L)
{
LNode *s = L;
while (s)
{
cout << s->data << ' ';
s = s->next;
}
}
int main()
{
LNode *L;
createList(L);
disp(L);
return 0;
}
对比思路:
6. 单链表第i个节点的前驱节点
#include <bits/stdc++.h>
using namespace std;
#define Max 50
/**
*查找第i个节点的前驱
*
*/
typedef struct LNode
{
int data; // 数据域
struct LNode *next; // 指针域,指向后继
} LNode, *linklist;
int a[9] = {1, 2, 3, 4, 5, 6, 7, 89, 9};
int n = 9;
// 1. 创建单链表
void createList(linklist &L)
{
LNode *s;
// 最初状态下,头指针 H 没有任何结点,所以,插入第一个元素,就相当于是创建结点 H
L = (linklist)malloc(sizeof(LNode));
L->data = a[0];
L->next = NULL;
for (int i = 1; i < n; i++)
{
s = (linklist)malloc(sizeof(LNode));
s->data = a[i];
s->next = L;
L = s;
}
};
// 打印输出
void disp(LNode *L)
{
LNode *s = L;
while (s)
{
cout << s->data << ' ';
s = s->next;
}
cout << ' ' << endl;
}
LNode *backpre(linklist L, int n)
{
int count = 0;
while (L)
{
if (count == n-2)
{
return L;
}
else
{
L = L->next;
count++;
}
}
return 0;
};
int main()
{
LNode *L;
createList(L);
disp(L);
cout << "第四个位置的前驱 " << backpre(L, 4)->data << endl;
return 0;
}
7. 单链表删除某个节点
void deleteX(linklist &L, int x)
{
if (L == NULL)
return;
LNode *r = L->next, *q, *f = L;
while (r)
{
if (r->data == x)
{
q = r; // q指向要删除的结点
r = r->next;// p->指向要删除结点的后驱
f->next = r;// q的前驱指向q的后驱
free(q);
}
else
{
f = f->next;
r = r->next;
}
}
}
8. 尾插法建立单链表
#include <bits/stdc++.h>
using namespace std;
#define Max 50
/**
*头插法建立单链表,无头节点
*
*/
typedef struct LNode {
int data; // 数据域
struct LNode* next; // 指针域,指向后继
} LNode, *linklist;
int a[4] = {1, 2, 3, 4};
int n = 4;
void createList(linklist& L) {
LNode* s;
// 最初状态下,头指针 H
// 没有任何结点,所以,插入第一个元素,就相当于是创建结点 H
L = (linklist)malloc(sizeof(LNode));
L->data = 0;
L->next = NULL;
for (int i = 0; i < n; i++) {
s = (linklist)malloc(sizeof(LNode));
s->data = a[i];
s->next = L->next; // 头插法
L->next = s;
}
};
void createRailList(linklist& L) {
LNode* s;
L = (linklist)malloc(sizeof(LNode));
L->data = 0;
L->next = NULL;
LNode* r = L;
for (int i = 0; i < n; i++) {
s = (linklist)malloc(sizeof(LNode));
s->data = a[i]; // 尾插法
r->next = s;
r = s;
}
r->next = NULL;
};
void disp(LNode* L) {
LNode* s = L->next;
while (s) {
cout << s->data << ' ';
s = s->next;
}
}
int main() {
LNode* L;
cout << "头插法:";
createList(L);
disp(L);
cout << endl;
LNode* H;
cout << "尾插法:";
createRailList(H);
disp(H);
cout << endl;
return 0;
}
9. 删除线性表的最小元素
从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。 空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行
#include <bits/stdc++.h>
// 从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。
// 空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行
using namespace std;
#define Max 50
typedef struct sqlist {
int a[Max] = {45, 24, 556, 87, 78, 67, 6, 67, 99};
int length = 9;
} sqlist;
// 找出顺序表中的最小值,并返回位置
bool finMain(sqlist& s, int& a) {
if (s.length == 0) { // 如果长度为0,直接返回false
return false;
}
int min = s.a[0]; // 先取第一个为最小的元素
int flag = 0;
for (int i = 0; i < s.length; i++) {
if (min > s.a[i]) { // 如果mind大于其他元素,说明不是最小元素
min = s.a[i];
flag = i;
}
}
a = s.a[flag];
s.a[flag] = s.a[s.length - 1];
return true;
}
void disp(sqlist list) {
for (int i = 0; i < list.length; i++) {
cout << list.a[i] << " ";
}
}
int main() {
sqlist s;
int a;
cout << "删除最小元素前:";
disp(s);
cout << endl;
finMain(s, a);
cout << "删除后:";
disp(s);
return 0;
}
10.合并链表
#include <bits/stdc++.h>
using namespace std;
typedef struct LNode {
int data;
struct LNode* next;
} LNode, *LinkList;
int a[10] = {1, 2, 3, 4, 5};
int n = 5;
int b[10] = {6, 7, 8, 9, 10};
void createList(LNode*& L, int arr[]) {
L = new LNode();
L->data = 0;
L->next = NULL;
LNode *s, *r = L;
for (int i = 0; i < n; i++) {
s = new LNode();
s->data = arr[i]; // 尾插法
r->next = s;
r = s;
}
r->next = NULL;
};
void disp(LNode* L) {
LNode* p = L->next;
while (p) {
cout << p->data << " ";
p = p->next;
}
}
void concat(LinkList p, LinkList q) {
LNode* r; // 标记指针,用来指向下一个元素,一直遍历的尾部
while (p) { // 第一个链表未遍历到最后一个元素
r = p;
p = p->next;
};
if (r->next == NULL) {
r->next = q->next; // 将第一个链表的最后一个元素的指针指向下一个链表
}
};
int main() {
LNode* L;
LNode* f;
createList(L, a);
createList(f, b);
cout << "打印初始链表a: ";
disp(L);
cout << endl;
cout << "打印初始链表b: ";
disp(f);
cout << endl;
concat(L, f);
cout << "合并后链表z: ";
disp(L);
cout << endl;
return 0;
}
11.构造循环单链表
采用尾插法,最后一个节点,再指向头结点。
#include <bits/stdc++.h>
using namespace std;
typedef struct LNode {
int data;
struct LNode* next;
} LNode;
int a[100] = {1, 2, 3, 4, 5};
int n = 5;
void createList(LNode*& L) {
L = new LNode();
L->data = 0;
L->next = NULL;
LNode* s;
LNode* r = L;
for (int i = 0; i < n; i++) {
s = new LNode();
s->data = a[i];
r->next = s;
r = s;
}
r->next = L; // 将最后的尾指针,指向头结点
};
void disp(LNode* L) {
LNode* p = L->next;
int i = 0;
while (p) {
// cout << p->data << " ";
// p = p->next;
if (i < 10) {
i++;
cout << p->data << " ";
p = p->next;
} else {
break; // 大于则跳出循环
}
}
}
int main() {
LNode* L;
createList(L);
cout << "循环单链表的打印:";
disp(L);
return 0;
}