当前位置: 首页 > news >正文

数据结构与算法-顺序表应用

一.通讯录的创建

首先我们要理解的是通讯录本身就是以顺序表为底层的

只不过顺序表中的数组,这里我们是用结构体来替代,用来存储用户的信息

由于是通讯录的本质就是顺序表,所以顺序表的任何方法它都能套用

Contact.h:

#pragma once
#define Name_MAX 20
#define Gender_MAX 20
#define Tel_MAX 20
#define ADDR_MAX 100//定义联系人数据 自定义结构体
//姓名 性别 年龄 电话 地址
typedef struct personInfo
{char name[Name_MAX];char gender[Gender_MAX];int age;char tel[Tel_MAX];char addr[ADDR_MAX];
}peoInfo;//重命名为peoInfo//把顺序表改个名字,叫做通讯录
//前置声明,用结构体SL没命名之前的声明
//SL是在结构体创建后才改的名
typedef struct SeqList Contact;//初始化
void ContactInit(Contact* con);//销毁
void ContactDesTroy(Contact*con);//添加数据
void ContactAdd(Contact* con);//删除
void ContactDel(Contact* con);//修改
void ContactModify(Contact* con);
//
//查找
void ContactFind(Contact* con);
//
//展示
void ContactShow(Contact* con);

SeqList.h:

这个是顺序表本身的运用代码的头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
#include<string.h>
//定义顺序表的结构//#define N 100
//
静态顺序表
//struct SeqList
//{
//	int arr[N];
//	int size;//有效数据个数
//};typedef peoInfo SLDataType;
//动态顺序表
typedef struct SeqList
{SLDataType* arr;int size; //有效数据个数int capacity; //空间大小
}SL;//typedef struct SeqList SL;//顺序表初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestroy(SL* ps);
//void SLPrint(SL s);//头部插入删除 / 尾部插入删除
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);void SLPopBack(SL* ps);
void SLPopFront(SL* ps);//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);//查找数据
//int SLFind(SL* ps, SLDataType x);

Contact.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
#include"Contact.h"void ContactInit(Contact* con)
{SLInit(con);
}void ContactDesTroy(Contact* con)
{SLDestroy(con);
}//添加数据
void ContactAdd(Contact* con)
{peoInfo info;printf("请输入联系人姓名:\n");scanf("%s", info.name);printf("请输入联系人性别:\n");scanf("%s", info.gender);printf("请输入联系人年龄:\n");scanf("%d", &info.age);printf("请输入联系人电话:\n");scanf("%s", info.tel);printf("请输入联系人地址:\n");scanf("%s", info.addr);//添加SLPushBack(con,info);
}//以名字为依据查找数据
int FindByName(Contact* con, char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name))return i;}return -1;
}//删除
void ContactDel(Contact* con)
{//删除的数据一定要存在才能删除//查找(名字为依据)(依据不固定)char name[Name_MAX];printf("请输入你要删除的联系人的名字:\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("删除失败,联系人不存在\n");return;}SLErase(con, find);printf("删除成功\n");
}//展示
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%3s %3s  %3d  %3s  %3s\n",con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}//修改
void ContactModify(Contact* con)
{char name[Name_MAX];printf("请输入你要修改的联系人的名字:\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("修改失败,联系人不存在\n");return;}printf("请输入新的姓名:\n");scanf("%s", con->arr[find].name);printf("请输入新的性别:\n");scanf("%s", con->arr[find].gender);printf("请输入新的年龄:\n");scanf("%d", &con->arr[find].age);printf("请输入新的电话:\n");scanf("%s", con->arr[find].tel);printf("请输入新的住址:\n");scanf("%s", con->arr[find].addr);printf("修改成功!\n");
}//查找
void ContactFind(Contact* con)
{char name[Name_MAX];printf("请输入要查找的联系人姓名\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要查找的联系人数据不存在!\n");return;}// 姓名 性别 年龄 电话  地址// 11   11   11   11   11printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%3s   %3s   %3d   %3s   %3s\n", con->arr[find].gender,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}

SeqList.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{if (ps->arr) //等价于  if(ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->size = ps->capacity = 0;
}
void SLCheckCapacity(SL* ps)
{//插入数据之前先看空间够不够if (ps->capacity == ps->size){//申请空间//malloc calloc realloc  int arr[100] --->增容realloc//三目表达式int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间if (tmp == NULL){perror("realloc fail!");exit(1);//直接退出程序,不再继续执行}//空间申请成功ps->arr = tmp;ps->capacity = newCapacity;}
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{温柔的解决方式//if (ps == NULL)//{//	return;//}assert(ps); //等价与assert(ps != NULL)//ps->arr[ps->size] = x;//++ps->size;SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//先让顺序表中已有的数据整体往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];//arr[1] = arr[0]}ps->arr[0] = x;ps->size++;
}//void SLPrint(SL s)
//{
//	for (int i = 0; i < s.size; i++)
//	{
//		printf("%d ", s.arr[i]);
//	}
//	printf("\n");
//}
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//顺序表不为空//ps->arr[ps->size - 1] = -1;--ps->size;
}
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//数据整体往前挪动一位for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1]; //arr[size-2] = arr[size-1]}ps->size--;
}//指定位置之前添加
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}查找数据
//int SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	int i = 0;
//	for (int i =0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//			return i;
//	}
//	return -1;
//}

add.c:

这个是代码运行的源文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
#include"Contact.h"//void SLTest01()
//{
//	SL sl;
//	SLInit(&sl);
//	SLPushBack(&sl, 1);
//	SLPushBack(&sl, 2);
//	SLPushBack(&sl, 3);
//	SLPushBack(&sl, 4);
//	SLPrint(sl);//1 2 3 4
//
//	SLPushFront(&sl, 5);
//	SLPushFront(&sl, 6);
//
//	βɾ
//	SLPopBack(&sl);
//	SLPrint(sl);//1 2 3 
//	SLPopBack(&sl);
//	SLPrint(sl);
//	SLPopBack(&sl);
//	SLPrint(sl);
//	SLPopBack(&sl);
//	SLPrint(sl);
//	SLPopFront(&sl);
//	SLPrint(sl);
//	...........
//	SLDestroy(&sl);
//}
//
//void SLTest02()
//{
//	SL sl;
//	SLInit(&sl);
//
//
//	SLPushBack(&sl, 1);
//	SLPushBack(&sl, 2);
//	SLPushBack(&sl, 3);
//	SLPushBack(&sl, 4);
//
//
//	/*SLInsert(&sl, 0, 5);*/
//
//	/*SLErase(&sl, 0);*/
//	/*SLPrint(sl);
//	int find=SLFind(&sl, 4);
//	if (find< 0)
//		printf("没找到\n");
//	else
//		printf("找到了,下标是:%d\n",find);*/
//
//
//
//	SLDestroy(&sl);
//}void ContactTest01()
{Contact con;ContactInit(&con);ContactAdd(&con);ContactAdd(&con);ContactShow(&con);/*ContactDel(&con);*/ContactModify(&con);ContactShow(&con);ContactFind(&con);ContactDesTroy(&con);}//int main()
//{
//	/*SLTest01();*///SLTest02();//ContactTest01();
//	return 0;
//}int main()
{ContactTest01();
}

二.移除元素

代码详解:

int removeElement(int* nums, int numsSize, int val) {int str = 0 ;int dst = 0 ;while(str<numsSize){if(nums[str]==val){str++;}else{nums[dst++]=nums[str++];}}return dst;
}

tip:

此处使用双指针的方法,还可以使用新的数组进行替换,但是题目要求受限

三.合并两个有序数组

代码详解:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int l1 = m - 1;int l2 = n - 1;int l3 = m + n - 1;while(l1 >= 0 && l2 >= 0 ){if(nums1[l1]<nums2[l2]){nums1[l3--]=nums2[l2--];}else{nums1[l3--]=nums1[l1--];}}while(l2>=0){nums1[l3 -- ] = nums2[l2--];}
}

相关文章:

  • 网络原理 - 4(TCP - 1)
  • AI深度伪造视频用于诈骗的法律定性与风险防范
  • Mysql的redolog
  • React:<></>的存在是为了什么
  • VMwaer虚拟机复制粘贴、ROS系统安装
  • 嵌入式软件测试的革新:如何用深度集成工具破解效率与安全的双重困局?
  • 前端路由 ( 1 ) | history 原理
  • 网络流的各种模型+题单
  • C语言高频面试题目——内联函数和普通函数的区别
  • python番外
  • 部署Megatron - LM,快速上手使用
  • P3909 异或之积 解题报告
  • 使用 Nacos 的注意事项与最佳实践
  • 深入理解CSS中的`transform-origin`属性
  • 树莓派超全系列教程文档--(40)树莓派config.txt旧版GPIO控制、超频及条件过滤器
  • 2025.4.22学习日记 JavaScript的常用事件
  • 电力系统中为什么采用三相交流电?
  • 虚拟机的网络配置
  • Springboot整合MyBatisplus和快速入门
  • apt --fix-broken install报错? Nvidia-driver没办法安装x
  • 2025年一季度上海市国民经济运行情况
  • 王励勤谈国乒备战洛杉矶奥运会:要对六块金牌制定新的战略
  • 视频·世界读书日|王弘治:信息轰炸也会让文化体力透支
  • 告别国泰海通,黄燕铭下一站将加盟东方证券,负责研究业务
  • 委托第三方可一次性补缴十多万元的多年社保?广州多人涉嫌被骗后报警
  • 外交部:中方近日派出停火监督组赴缅,监督缅军和果敢同盟军停火