本章总结单链表的顺序存储方式及其C++实现,重点的理论只需要熟背以下3条:
1.线性表是0个或者多个数据元素的有限序列,其中数据元素类型相同
2.线性表可以逐项访问和顺序存储
3.有顺序存储和链式存储两种存储方式。
接下来,通过动态数组的方式实现顺序存储结构的单链表:
首先在目录文件夹中定义一个头文件Dymanic_Array.h,便于代码的复用,具体内容包含:
#ifndef DYNAMIC_ARRAY_H
#define DYNAMIC_ARRAY_H
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
//动态增长内存,将存放的数据的内存放在堆上面。
//动态数组:申请内存 拷贝数据 释放内存
//容量capacity表示我的这块内存空间中一共可以存放多少元素
//size用于记录当前数组中具体的元素个数
typedef struct Dymanic_Array
{
int *pAddr; //存放数据的地址
int size;
int capacity;
}Dymanic_Array;
//由于返回的各种数据要存放在结构体中,因此要定义位结构体类型的方法
Dymanic_Array*Init_Array();
//插入
void Push_Back_Array(Dymanic_Array* arr,int val);
//两个参数的值分别为目标数组,以及插入元素的值
//根据值删除
void RemoveByValue_Array(Dymanic_Array* arr,int val);
//根据位置删除
void RemoveByPos_Array(Dymanic_Array* arr,int pos);
//查找
int Find_Array(Dymanic_Array* arr,int val);
//打印
void Print_Array(Dymanic_Array* arr);
//释放内存
void FreeSpace_Array(Dymanic_Array* arr);
//清空数组
void Clear_Array(Dymanic_Array* arr);
//获得当前容器的容量
int Capacity_Array(Dymanic_Array* arr);
//获取当前容器中元素的个数
int Size_Array(Dymanic_Array* arr);
//获取某一位置的元素
int At_Array(Dymanic_Array* arr,int pos);
#endif
在此头文件中,主要声明了该数据结构的各种方法,包含:初始化、插入元素、按元素值删除元素、按位置删除元素、查找元素、打印元素、释放内存、清空内容、获取容量、获取元素个数、获取某位置上的元素。
然后,在同一目录下创建Dymanic_Array.c文件,用于实现数据结构的具体操作。头部声明头文件:
#include "Dymanic_Array.h"
初始化数据结构
Dymanic_Array*Init_Array(){ //申请内存 Dymanic_Array* myArray =(Dymanic_Array*) malloc(sizeof(Dymanic_Array)); //动态分配内存时一定要记住强转类型的操作! //初始化 myArray->size=0; myArray->capacity=20; //预定义容量为20 myArray->pAddr=(int *)malloc(sizeof(int)*myArray->capacity); //获取动态数组首地址 return myArray; }
插入元素
void Push_Back_Array(Dymanic_Array* arr,int value){
if(arr==NULL)
return;
//判断空间是否足够
if(arr->size == arr->capacity)
{
//1.将新的空间扩展为原有的2倍
int* newSpace =(int*)malloc(sizeof(int)* arr->capacity*2);
//2.拷贝数据到新的空间
memcpy(newSpace,arr->pAddr,arr->capacity*sizeof(int));
//3.释放旧空间的内存
free(arr->pAddr);
//更新容量
arr->capacity= arr->capacity*2;
arr->pAddr=newSpace;
}
//插入新元素
arr->pAddr[arr->size] =value;
arr->size++;
}
按元素值删除元素
void RemoveByValue_Array(Dymanic_Array* arr,int value){
if(arr==NULL)
return;
//找到值的位置
int pos=-1;
for(int i=0;i<arr->size;i++)
{
if(arr->pAddr[i]==value)
{
pos=i;
break;
//因为只删除一个,因此找到后就要退出循环
//如果想删除多个,只需要将位置存储在数组里面即可~
}
}
//再度根据位置删除!
RemoveByPos_Array(arr,pos);
}
按位置删除元素
void RemoveByPos_Array(Dymanic_Array* arr,int pos){
if(arr==NULL)
return;
//判断位置是否有效
if(pos<0||pos>arr->size)
return;
//删除元素:本质思想是元素覆盖!
for(int i=pos;i<arr->size-1;i++)
{
arr->pAddr[i]=arr->pAddr[i+1];
}
//数量减一
arr->size--;
}
查找元素
int Find_Array(Dymanic_Array* arr,int value){
if(arr==NULL)
return -1;
//统一未寻找到的返回值
//查找
int pos=-1;
for(int i=0;i<arr->size;i++)
{
if(arr->pAddr[i]==value)
{
pos=i;
break;
//同按照位置删除的操作完全一致
}
}
return pos;
}
打印元素
void Print_Array(Dymanic_Array* arr){
if(arr==NULL)
return;
for(int i=0;i< arr->size;i++)
printf("%d ",arr->pAddr[i]);
printf("\n");
}
释放内存
void FreeSpace_Array(Dymanic_Array* arr){
if(arr==NULL)
return;
//如果传入的是空数组,直接返回空,增加程序的健壮性,其他函数内部的操作亦同理~
if(arr->pAddr!=NULL)
{
free(arr->pAddr);
}
free(arr);
}
清空内容
void Clear_Array(Dymanic_Array* arr){
if(arr==NULL)
return;
arr->size=0;
//相当于直接跳过初始化pAddr的过程,清空内部的元素
}
获取容量
int Capacity_Array(Dymanic_Array* arr){
if(arr==NULL)
return -1;
return arr->capacity;
}
获取元素个数
int Size_Array(Dymanic_Array* arr){
if(arr==NULL)
return -1;
return arr->size;
}
获取某位置上的元素
int At_Array(Dymanic_Array* arr,int pos){
return arr->pAddr[pos];
}
最后,在同一目录下创建main.cpp/main.c文件来测试该数据结构的功能是否能实现,此次笔者采用c++,如下:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include"Dymanic_Array.h"
using namespace std;
void test01(){
Dymanic_Array*myArray=Init_Array();
//初始化
for(int i=1;i<=10;i++)
Push_Back_Array(myArray,i);
Print_Array(myArray);
FreeSpace_Array(myArray);
}
int main(int argc, char** argv) {
test01();
return 0;
}
综上,该数据结构能满足线性表顺序存储中的常见操作。