以下内容是本人在学习王道C语言训练营的相关代码,代码主要适用于考研的同学,但数据结构的思想是大致一样。
一、顺序表插入操作
声明:项目的结构是C++,且以数组的形式表示顺序表。
-
逻辑思想
插入操作核心步骤:
- 检查插入的元素是否在合理范围内(1 <= i <= length+1) i指元素实际位置
- 顺序表内存还有空间
- 如果前面两个问题满足,则将待插入元素及后面的元素位置依次后移一位,否则不能插入
- 将待插入元素赋值到空位置中
- 顺序表的长度加一
-
顺序表初始化和插入
注意点:
1.bool ListInsert(SqList *L,int pos,ElemType ele)
中的第一个参数要使用指针,因为要改变该结构体的内容(地址传递)
2.符号.和->
的作用和区别
-
A.a则A为对象或者结构体; 点号(.):左边必须为实体。
-
A->a则A为指针,->是成员提取,A->a是提取A中的成员a,A只能是指向类、结构、联合的指针; 箭头(->):左边必须为指针;
3.if (pos < 1 || pos > L->length+1)
中的之所以要length+1 是为了说明可以在最后插入元素
#include <stdio.h>
#define MaxSize 50
typedef int ElemType;//elemtype表示任意类型
//定义顺序表
typedef struct {
ElemType data[MaxSize];//以数组的形式,ElemType让
int length;//顺序表的长度
} SqList;
//插入方法,参数分别为顺序表指针,插入的位置,插入的元素值
bool ListInsert(SqList &L,int pos,ElemType ele){
//判断插入的位置是否在合理范围内
if (pos < 1 || pos > L.length+1){//length+1 是为了在说明可以在最后插入
return false;
}
//数组是否内存已满
if (L.length == MaxSize){
return false;
}
//把后面的元素依次往后移
for (int i = L.length; i >= pos ; i--) {
L.data[i] = L.data[i-1];
}
L.data[pos - 1] = ele;
L.length++;//将数组长度加加
return true;
}
//打印顺序表
void PrintList(SqList L){
for (int i = 0; i < L.length; i++) {
printf("%3d",L.data[i]);
}
printf("\n");
}
int main() {
//初始化
SqList L;
bool ret;
//手动添加顺序
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;//设置长度,很重要,刚刚没有写句话,就打印了failed
ret = ListInsert(L,2,60);
if (ret){
printf("insert sqList success\n");
PrintList(L);
} else{
printf("insert sqList failed\n");
}
}
二、顺序表删除操作
//删除顺序表的元素
bool ListDelete(SqList &L,int i,ElemType &ele){
//删除的元素是否在合理范围内
if (i < 1 || i > L.length){
return false;//一旦走到return函数就结束了
}
ele = L.data[i-1];
for (int j = i - 1; j < L.length - 1; j++) {
//将待删除元素后面的元素依次向前移
L.data[j] = L.data[j+1];
}
L.length--;
return true;
}
int main() {
//初始化
SqList L;//结构体
bool ret;
//手动添加顺序
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;//设置长度,很重要,刚刚没有写句话,就打印的defeat
ret = ListInsert(L,2,60);
// if (ret){
// printf("insert sqList success\n");
// PrintList(L);
// } else{
// printf("insert sqList defeat\n");
// }
// printf("----------------\n");
//删除的元素放到del
ElemType del;
ret = ListDelete(L,1,del);
if (ret){
printf("delete sqList success\n");
PrintList(L);
} else{
printf("delete sqList failed\n");
}
}
三、顺序表的查询
//查询顺序表位置
int LocalElem(SqList L, int i){//不改变结构体,因此不用引用
for (int j = 0; j < L.length; j++) {
if (L.data[j] == i){
return j+1;//因为j是数组的下标,所以加一
}
}
return 0;
}
int main(){
int pos;//存储元素的位置
pos = LocalElem(L, 60);
if (pos){
printf("chaXun sqList success\n");
printf("%d\n",pos);
} else{
printf("chaXun sqList failed\n");
}
}
四、三种传递区别
1.【值传递】如果形参为非引用的传值方式,则生成局部临时变量接收实参的值
void Swap (int left, int right) //值传递的方式无法实现交换,因为传参时对于参数left和right拷贝一临时副本,交换的是副本值,因为其是临时变量函数退出,变量销 { //毁,并不会影响外部left和right的值。
int temp = left;
left = right ;
right = temp ;
}
2.【引用传递】如果形参为引用类型,则形参是实参的别名。
void Swap (int& left, int& right)//使用引用的话,不做临时拷贝,&的使用说明此处只是原参数的另一个名字而已,所以修改时直接在原参数的基础上修改变量值。
{
int temp = left;
right = left ;
left = temp ;
}
3.【指针传递】
void Swap (int* pLeft, int* pRight)//传入的是地址,因为地址是唯一的,所以指针通过地址的访问进而可修改其内容。
{
int temp = *pLeft;
*pLeft = *pRight;
*pRight = temp;