如何用C语言创建一个顺序表,并实现基础的 “ 增删改查 ” 功能
·
1. 顺序表(sqlist)
顺序表:是数据结构里的线性结构,数据之间呈现线性关系,且在内存上,连续存储(顺序存储)。顺序表是线性表的一种,另外线性表还包括链表。
2. 顺序表的创建
完成顺序表的一系列操作,首先要创建3个文件:sqlist.h 、sqlist.c 、main.c 。
(1)在头文件 sqlist.h 中,作以下定义:
#ifndef _sqlist_h_
#define _sqlist_h_
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef int data_t;//重命名一个int的数据类型data_t, 专门用来修饰顺序表中的data数据
#define SIZE 10 //宏定义数组大小,可修改
//顺序表结构体
typedef struct{
data_t data[SIZE];
int last;//表尾指针
}sqlist;
//创建顺序表
sqlist *sqlist_create();
以上包含了一些基本头文件,对相关数据的准备(宏定义、重命名数据类型),定义了顺序表的结构体,以及创建顺序表的函数定义。
(2)在 sqlist.c 文件中封装创建顺序表的功能
#include "sqlist.h"
//创建数据表
sqlist *sqlist_create()
{
//给顺序表结构体手动分配空间
sqlist *head = (sqlist *)malloc(sizeof(sqlist));
//验证是否成功申请到了空间
if (NULL == head){
printf("malloc failed!\n");
return NULL;
}
memset(head, 0, sizeof(sqlist));//给申请到的空间填充0(视情况可省略)
head->last= -1;//初始化尾指针
return head;//将申请到的空间首地址返回
}
(3)在主函数中调用封装的创建函数
int main(int argc, char *argv[])
{
//创建链表
node *head = linklist_create ();//结构体指针接收数据
//判断是否创建成功
if (head == NULL)
{
printf("malloc failed!\n");
return -1;
}
return 0;
}
3. 顺序表的基础附属操作
要操作顺序表,少不了一系列的附属功能(判空、判满、清空、求长度、显示、回收),实现这些功能让你的顺序表更健壮!
(1)头文件 sqlist.h 中的定义
//判空
int sqlist_empty(sqlist *head);//参数接收首地址
//判满
int sqlist_full(sqlist *head);
//清空顺序表
int sqlist_clear(sqlist *head);
//获取顺序表中有效数据长度
int sqlist_length(sqlist *head);
//显示顺序表中数据
void sqlist_display(sqlist *head);
//回收顺序表
void sqlist_destroy(sqlist *head);
(2)在 sqlist.c 中封装功能
//判空
int sqlist_empty(sqlist *head)
{
if (-1 == head->last)
return 1;
else
return 0;
//或者可以使用三目运算符
//return ((-1 == head->last) ? 1 : 0);
}
//判满
int sqlist_full(sqlist *head)
{
return ((SIZE - 1 == head->last) ? 1 : 0);
}
//清空顺序表
int sqlist_clear(sqlist *head)
{
head->last = -1;
}
//获取顺序表中有效数据长度
int sqlist_length(sqlist *head)
{
return head->last + 1;
}
//显示顺序表中数据
void sqlist_display(sqlist *head)
{
for(int i = 0; i <= head->last; i++)
printf("%-3d",head->data[i]);
puts(" ");
}
//回收顺序表
void sqlist_destroy (sqlist *head)//也可用二级指针
{
free (head);
}
(3)在主函数 main.c 中调用
这些函数除了回收顺序表函数之外,在主函数中一般不会单独调用,用于辅助实现 “ 增删改查 ” 功能,不可或缺。
//回收顺序表
sqlist_destroy(head);
head == NULL;
顺序表是malloc开辟的空间,需要手动释放回收,否则会导致空间泄露。
4. 顺序表 “ 增删改查 ” 功能的实现
(1)在头文件 sqlist.h 中的定义
//按位置插入数据
int sqlist_pos_insert(sqlist *head,int pos,data_t data);
//按位置删除数据
int sqlist_pos_delete(sqlist *head,int pos);
//按元素删除数据
int sqlist_data_delete(sqlist *head,data_t data);
//按位置修改数据
int sqlist_pos_update(sqlist *head,int pos,data_t data);
//按元素修改数据
int sqlist_data_update(sqlist *head,data_t old_data, data_t new_data );
//按位置查找元素
data_t sqlist_pos_search(sqlist *head,int pos);
//按元素查找位置
int sqlist_data_search(sqlist *head,data_t data);
(2)在 sqlist.c 文件中封装功能
1)按位置插入数据
//按位置插入数据
int sqlist_pos_insert(sqlist *head,int pos,data_t data)
{
//判满
if (sqlist_full(head))
{
printf("Sqlist is full! Insert failed!");
return -1;
}
//判断pos是否有效
int len = sqlist_length(head);
if ((pos<0) || (pos > len)){
printf("Insert pos is invalid!\n");
return -1;
}
//腾出pos位置
for(int i = head->last+1; i > pos; i--)
{
head->data[i] = head->data[i-1];
}
//修改数据
head->data[pos] = data;
head->last += 1;
return 0;
}
2)删除数据(按元素值、按位置)
//按位置删除数据
int sqlist_pos_delete(sqlist *head,int pos)
{
//判空(可省略)
if (sqlist_empty(head))
{
printf("Sqlist is empty! Delete failed!");
return -1;
}
//判断pos是否有效
int len = sqlist_length(head);
if ((pos<0) || (pos > len)){
printf("Delete pos is invalid!\n");
return -1;
}
//移动删除
for(int i = pos+1; i < head->last+1; i++)
{
head->data[i-1] = head->data[i];
}
//将表中有效数据量-1
head->last -= 1;
return 0;
}
//按元素删除数据
int sqlist_data_delete(sqlist *head,data_t data)
{
//判空
if (sqlist_empty(head))
{
printf("Sqlist is empty! Delete failed!");
return -1;
}
//删除数据
for(int i = 0; i < head->last+1; i++)
{
//先找到删除元素的位置,再调用按位置删除函数(书写简便,但效率较低)
if (data == head->data[i])
sqlist_pos_delete(head, i);
}
}
3)修改数据(按位置、按元素值)
//按位置修改数据
int sqlist_pos_update (sqlist *head, int pos, data_t data)
{
//判空(可省略)
if (sqlist_empty(head))
{
printf("Sqlist is empty! Update failed!");
return -1;
}
//判断pos是否有效
int len = sqlist_length(head);
if ((pos<0) || (pos >= len)){
printf("Update pos is invalid!\n");
return -1;
}
//修改数据
head->data[pos] = data;
}
//按元素值修改数据
int sqlist_data_update(sqlist *head, data_t old_data, data_t new_data)
{
//判空
if (sqlist_empty(head))
{
printf("Sqlist is empty! Update failed!");
return -1;
}
//遍历寻找要修改的数据,再赋新值
for(int i = 0; i < head->last+1; i++)
{
if (old_data == head->data[i])
head->data[i] = new_data;
}
}
4)查找数据(按位置找元素值,按元素值找位置)
//按位置查找元素
data_t sqlist_pos_search (sqlist *head, int pos) //用data_t类型接收返回的数据值
{
//判空(可省略)
if (sqlist_empty(head))
{
printf("Sqlist is empty! search failed!");
return -1;
}
//判断pos是否有效
int len = sqlist_length (head);
if ((pos<0) || (pos >= len)){
printf ("Search pos is invalid!\n");
return -1;
}
//直接返回pos位置的数据值
return head->data[pos];
}
//按元素查找位置
int sqlist_data_search (sqlist *head, data_t data)
{
//假设顺序表中可能有多个相同元素
int count = 0;
//查找匹配元素的位置
for (int i = 0; i < head->last+1; i++)
{
if (data == head->data[i])
{
//记录匹配元素的个数
count++;
//每找到一个匹配元素,打印它的位置
printf ("%-3d", i);
}
}
puts("");
//如果计数为0,提示顺序表中没有找到匹配元素
if (count == 0){
printf ("Sqlist does not have this data!");
return -1;
}
return 0;
}
(3)在主函数 main.c 中简单验证顺序表的 “ 增删改查 ” 功能
//按位置插入元素
//头插10个数
printf("插入10个数。\n");
int i=10;
while(i--)
{
sqlist_pos_insert(head, 0, i+1);
}
//展示插入结果
sqlist_display(head);
//按位置删除元素
printf("删除标号为3的元素。\n");
sqlist_pos_delete(head, 3);
sqlist_display(head);
//按元素删除数据
printf("删除数字2。\n");
sqlist_data_delete(head, 2);
sqlist_display(head);
//按位置修改数据
printf("修改标号为1的元素值为9。\n");
sqlist_pos_update(head, 1, 9);
sqlist_display(head);
//按元素修改数据
printf("修改元素值为9的元素值为0。\n");
sqlist_data_update(head, 9, 0);
sqlist_display(head);
//按位置查找元素
printf("标号为7的元素值为:%d\n",sqlist_pos_search(head, 7));
//按元素查找位置
printf("数值为0的元素位置标号为:");
sqlist_data_search(head, 0);
1)运行结果如下
插入10个数。
1 2 3 4 5 6 7 8 9 10
删除标号为3的元素。
1 2 3 5 6 7 8 9 10
删除数字2。
1 3 5 6 7 8 9 10
修改标号为1的元素值为9。
1 9 5 6 7 8 9 10
修改元素值为9的元素值为0。
1 0 5 6 7 8 0 10
标号为7的元素值为:10
数值为0的元素位置标号为:1 6
注:在实际情况下,数据具有唯一性,可根据实际情况修改 “ 查找 ” 和 “ 修改 ” 的功能代码。
5. 总结
1. 顺序表访问、查找元素方便,但对经常进行插入和删除操作的情况不友好。
2. 若想让插入、删除功能的效率高,推荐了解链表的操作~
敬请期待下集:C语言链表的基本操作(linklist)
感谢观看!如有疑问欢迎提出!
----香菜小猫祝这位uu天天开心----
更多推荐
所有评论(0)