关于数据结构
前言:
数据结构一直是大多数人比较头疼的课程,里面弯弯绕很多,但是不可否认的是,他真的很重要。无论你选择考研还是找工作,数据结构一定是考试、面试、笔试的一个重点。博主就是之前学习了数据结构,但是前学后忘,最近刷一些算法题的时候,发现真的,忘得一干二净了。于是痛下决心,好好复习,整理成博客。故,废话不多说,我们开始总结吧。
关于数据结构:
数据结构:线性表(链表、顺序表)(栈、队列、串);
树形结构(二叉树);
网状结构;算法:
排序、查找、动态内存管理;
数据存储方式:
顺序存储(逻辑相邻,物理也相邻);
链式存储(逻辑相邻,物理不一定相邻)。注:以上所列仅为个人整理数据结构知识的一个框架,并不代表完整的知识体系。
定长顺序表
定长顺序表 顾名思义,就是长度固定的顺序表,基本上没有什么人使用它,不具有实用价值,仅作为数据结构的简单入门。
头文件(.h)
首先我们可以声明如下的头文件:
#pragma once // 防止头文件被重复引用
// 头文件:存放数据的定义和函数的声明
// 定长顺序表:没有实用价值,只是简单入门
#define SIZE 10
typedef struct SeqList
{
int elem[SIZE];// 存放数据
int len;// 有效数据的个数
}SeqList,*PSeqList;
// 初始化函数
void InitSeqList(PSeqList plist);
// 判空
bool IsEmpty(PSeqList plist);
// 插入数据:往plist的pos位置插入数据val
bool Insert(PSeqList plist,int val,int pos);
// 在plist中查找关键字key,找到返回下标,失败返回-1
int Search(PSeqList plist,int key);
// 删除plist中的第一个key
bool DeleteVal(PSeqList plist,int key);
// 删除plist中pos位置的值
bool DeletePos(PSeqList plist, int pos);
// 将pos位置的值赋值成newval
bool SetPos(PSeqList plist, int pos, int newval);
// 打印输出所有数据
void Show(PSeqList plist);
// 清空数据
void Clear(PSeqList plist);
// 销毁动态内存
void Destroy(PSeqList plist);
实现文件(.cpp)
我们可以在.cpp
文件中实现头文件里的各个函数部分:
// .cpp:存放函数的实现
#include "seqlist.h"
#include <stdio.h>
#include <assert.h>
// 判满
static bool IsFull(PSeqList plist)
{
return plist->len == SIZE;
}
// 初始化函数
void InitSeqList(PSeqList plist)
{
assert(plist != NULL);
if (plist == NULL) return;
plist->len = 0;// 当前还有有效数据
}
// 判空
bool IsEmpty(PSeqList plist)
{
return plist->len == 0;
}
// 插入数据:往plist的pos位置插入数据val
bool Insert(PSeqList plist, int val, int pos)
{
assert(plist != NULL);
if (plist == NULL) return false;
// 数据必须靠左,连续存放(当前设计决定)
if (pos < 0 || pos > plist->len || IsFull(plist))
{
return false;
}
// 移动数据
for (int i = plist->len - 1; i >= pos; i--)
{
plist->elem[i + 1] = plist->elem[i];
}
// 插入数据
plist->elem[pos] = val;
// 增加有效数据个数
plist->len++;
return true;
}
// 在plist中查找关键字key,找到返回下标,失败返回-1,非法返回-2
int Search(PSeqList plist, int key)
{
assert(plist != NULL);
if (plist == NULL) return -2;
int i = 0;
for (; i < plist->len; i++)
{
if (key == plist->elem[i])
{
return i;
}
}
if (i == plist->len)
{
return -1;
}
}
// 删除plist中的第一个key
bool DeleteVal(PSeqList plist, int key)
{
assert(plist != NULL);
int index = Search(plist,key);
return DeletePos(plist, index);
}
// 删除plist中pos位置的值
bool DeletePos(PSeqList plist, int pos)
{
assert(plist != NULL);
if (pos < 0 || pos > plist->len)
{
return false;
}
// 后面的数据往前移
for (int i = pos; i < plist->len-1; i++)
{
plist->elem[i] = plist->elem[i + 1];
}
// 有效数据个数-1
plist->len--;
return true;
}
// 将pos位置的值赋值成newval
bool SetPos(PSeqList plist, int pos, int newval)
{
if (pos < 0 || pos >= plist->len)
{
return false;
}
plist->elem[pos] = newval;
return true;
}
// 打印输出所有数据
void Show(PSeqList plist)
{
for (int i = 0; i < plist->len; i++)
{
printf("%d ", plist->elem[i]);
}
printf("\n");
}
// 清空数据:删除所有数据
void Clear(PSeqList plist)
{
assert(plist != NULL);
if (plist == NULL) return;
plist->len = 0;
}
// 销毁动态内存
void Destroy(PSeqList plist)
{
// 因为没有用到动态内存,所以不用销毁
Clear(plist);
}
简单测试
写完了让我们简单测一下这些功能:
#include <iostream>
#include "seqlist.h"
int main()
{
// 创建定长顺序表的一个变量:sl
SeqList sl;
// 对定长顺序表进行初始化
InitSeqList(&sl);
// 循环插入,因为指定了长度为10,所以只能插入:0-9
for (int i = 0; i < 15; i++)
{
Insert(&sl, i, i);
}
std::cout << "原始数据为:" << std::endl;
// 将该表的数据打印出来
Show(&sl);
// 查找顺序表里指定数值:8,查找成功返回下标
int s = 0;
std::cout << "请输入要查找的值:";
std::cin >> s;
int r = Search(&sl, s);
std::cout << "结果为:" << r << std::endl;
// 删除刚才查找的8号下标的数据
DeletePos(&sl,8);
// 重新打印
std::cout << "删除" << r << "号下标数据后:" << std::endl;
Show(&sl);
return 0;
}
相应的结果为: