线性表

线性表基本概念

  • 线性表是零个或者多个数据元素的有限序列
  • 数据元素之间是有顺序的
  • 数据元素个数是有限的
  • 数据元素的类型必须相同

线性表性质

  • a0为线性表的第一个元素,只有一个后继,没有前驱
  • an为线性表最后一个元素,只有一个前驱,没有后继
  • 除了a0和an外的其他元素ai,既有前驱,也有后继
  • 线性表能够逐项访问和顺序存取

线性表操作

  • 创建线性表
  • 销毁线性表
  • 清空线性表
  • 将元素插入线性表
  • 将元素从线性表中删除
  • 获取线性表中某个位置的元素
  • 获取线性表的长度

线性表的顺序存储

  • 用一段地址连续的存储单元依次存储线性表的数据元素

代码示例:

//.h头文件
#ifndef DENAMIC_ARRAY_H
#define DENAMIC_ARRAY_H

#define _CRT_SECURE_NO_WARNINGS

using namespace std;

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//定义结构体
//动态增长内存,策略将存放数据的内存
//动态数组申请内存,插入和拷贝数据
//capacity表示内存一共可以存放多少元素
//size记录当前数组元素个数
typedef struct DYNAMICARRAY
{
	int* pAddr;//存放数据地址
	int size;//当前有多少个元素
	int capacity;//容量容器最大可以容纳多少元素
}Dynamic_Array;

//写一系列的相关的对结构体操作的函数

//初始化
Dynamic_Array* Dynamic_Init_Array();

//插入
bool Push_Back_Array(Dynamic_Array* arr,int value);

//根据位置删除
bool Remove_Bypos_Array(Dynamic_Array* arr, int pos);

//根据值删除
bool Remove_Byvalue_Array(Dynamic_Array* arr, int value);

//查找
bool Find_Array(Dynamic_Array* arr, int value);

//释放动态数组的内存
bool Free_Space_Array(Dynamic_Array* arr);

//打印数组
void Print_Arrar(Dynamic_Array* arr);

//清空数组
bool Clear_Array(Dynamic_Array* arr);

//返回动态数组容量
int Capacity_Array(Dynamic_Array* arr);

//返回数组元素个数
int Size_Array(Dynamic_Array* arr);

//根据位置获取元素
int Get_Array(Dynamic_Array* arr, int address);

#endif // !DENAMIC_ARRAY_H

//.cpp文件
#include"DynamicArray.h"

// 初始化
Dynamic_Array* Dynamic_Init_Array()
{
	Dynamic_Array* myArray = (Dynamic_Array*)malloc(sizeof(Dynamic_Array));
	if (myArray == NULL)
	{
		printf("内存分配不成功");
		return NULL;
	}
	//初始化数据项
	myArray->capacity = 20;
	myArray->pAddr = (int*)malloc(sizeof(int) * myArray->capacity);
	myArray->size = 0;
	return myArray;
}

//插入
bool Push_Back_Array(Dynamic_Array* arr, int value)
{
	if (arr == NULL)
	{
		return false;
	}
	//判断空间是否足够
	if (arr->size == arr->capacity)
	{
		//第一步申请一块更大空间,默认新空间是旧空间的两倍
		int* newsapce = (int*)malloc(sizeof(int) * arr->capacity * 2);
		if (newsapce == NULL)
		{
			return false;
		}
		//第二步拷贝数据到新的空间
		memcpy(newsapce, arr->pAddr, arr->capacity * sizeof(int));
		//第三步释放旧内存
		free(arr->pAddr);
		//更新容量
		arr->pAddr = newsapce;
		arr->capacity = arr->capacity * 2;	
	}
	arr->pAddr[arr->size] = value;
	arr->size++;
	return true;
}

//根据位置删除
bool Remove_Bypos_Array(Dynamic_Array* arr, int pos)
{
	if (arr == NULL)
	{
		return false;
	}
	if (pos<0 || pos>arr->size)
	{
		return false;
	}
	for (int i = pos; i < arr->size; i++)
	{
		arr->pAddr[i] = arr->pAddr[i + 1];
	}
	arr->pAddr[arr->size] = 0;
	arr->size--;
	return true;
}

//根据值删除,删除数组中所有该值
bool Remove_Byvalue_Array(Dynamic_Array* arr, int value)
{
	if (arr == NULL)
	{
		return false;
	}
	//找到值的位置
	for (int i = 0; i < arr->size; i++)
	{
		if (arr->pAddr[i] == value)
		{
			Remove_Bypos_Array(arr, i);
		}
	}
	return true;
}

//查找
bool Find_Array(Dynamic_Array* arr, int value)
{
	if (arr == NULL)
	{
		return false;
	}
	int flag = 0;
	for (int i = 0; i < arr->size; i++)
	{
		if (arr->pAddr[i] == value)
		{
			flag = 1;
			printf("%d  ", arr->pAddr[i]);
		}	
	}
	if (flag == 0)
		printf("%d找不到,不存在于数组", value);
	printf("\n");
	return true;
}

//释放动态数组的内存
bool Free_Space_Array(Dynamic_Array* arr)
{
	if (arr->pAddr != NULL)
	{
		free(arr->pAddr);
	}
	free(arr);
	return true;
}

//打印数组
void Print_Arrar(Dynamic_Array* arr)
{
	if (arr == NULL)
	{
		return;
	}
	for (int i = 0; i < arr->size; i++)
	{
		printf("%d  ", arr->pAddr[i]);
	}
	printf("\n");
	return ;
}

//清空数组
bool Clear_Array(Dynamic_Array* arr)
{
	if (arr == NULL)
	{
		return true;
	}
	arr->size = 0;
	return true;
}

//返回动态数组容量
int Capacity_Array(Dynamic_Array* arr)
{
	if (arr==NULL)
	{
		return 0;
	}
	return arr->capacity;
}

//返回数组元素个数
int Size_Array(Dynamic_Array* arr)
{
	if (arr == NULL)
	{
		return 0;
	}
	return arr->size;
}

//根据位置获取元素
int Get_Array(Dynamic_Array* arr, int address)
{
	//if (arr==NULL)
	//{
	//	return -1;//表示出错
	//}
	return arr->pAddr[address];
}

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include"DynamicArray.h"

#define MARRAY_TRUE 1
#define MARRAY_FLASE 0

void test01()
{
	//初始化动态数组
	Dynamic_Array* myArray = Dynamic_Init_Array();
	//打印容量
	printf("数组容量:%d  ", Capacity_Array(myArray));
	printf("数组大小:%d\n", Size_Array(myArray));
	
	//插入元素
	for (int i = 0; i < 30; i++)
	{
		Push_Back_Array(myArray, i);
	}
	printf("数组容量:%d  ", Capacity_Array(myArray));
	printf("数组大小:%d\n", Size_Array(myArray));

	//打印
	Print_Arrar(myArray);

	//删除
	Remove_Bypos_Array(myArray, 0);
	Remove_Byvalue_Array(myArray, 5);

	//查找第五个位置
	printf("第5个元素是%d\n", Get_Array(myArray, 5));

	//打印
	Print_Arrar(myArray);

	//销毁
	Free_Space_Array(myArray);
}

int main(void)
{
	test01();
	system("pause");
	return 0;
}

线性表的链式存储

  • 不连续的内存空间
  • 由一系列的节点组成,每个节点包含两个域,指针域和数据域
  • 最后一个节点是NULL
//.h头文件
#ifndef _LINK_LIST_H
#define _LINK_LIST_H

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;

//链表结点
typedef struct LINKNODE
{
	void* data;//可以指向任何类型的数据
	struct LINKNODE* next;

}LinkNode;

//链表结构体
typedef struct LINKLIST
{
	LinkNode* head;
	int size;
	//不需要容量
}LinkList;

typedef void(*PRINTLINKNODE)(void*);


//初始化链表
LinkList* Init_LinkList();

//指定位置插入
void Insert_LinkList(LinkList* list, int pos,void* data);

//删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos);

//获得链表的长度
int Size_LinkList(LinkList* list);

//查找
int Find_LinkList(LinkList* list, void* data);

//返回第一个结点
void* Front_LinkList(LinkList* list);

//释放链表内存
void FreeSpace_LinkList(LinkList* list);

//打印链表结点
void Print_LinkList(LinkList* list,PRINTLINKNODE print);

#endif 
//.cpp实现文件
#include"LinkList.h"

typedef void(*PRINTLINKNODE)(void*);

//初始化链表
LinkList* Init_LinkList()
{
	LinkList* list = (LinkList*)malloc(sizeof(LinkList));
	if (list == NULL)
	{
		return NULL;
	}
	list->head = (LinkNode*)malloc(sizeof(LinkNode));
	if (list->head == NULL)
	{
		return NULL;
	}
	list->head->data = NULL;
	list->head->next = NULL;
	list->size = 0;
	return list;
}

//指定位置插入
void Insert_LinkList(LinkList* list, int pos, void* data)
{
	if (list == NULL || data == NULL)
	{
		return;
	}

	//友好处理,pos越界
	if (pos<0 || pos>list->size)
	{
		pos = list->size;
	}
	//创建新的结点
	LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
	if (newNode == NULL)
	{
		return;
	}
	newNode->data = data;
	newNode->next = NULL;
	//找结点
	//辅助指针变量
	LinkNode* pCurrent = list->head;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}
	//新结点入链表
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;
	//链表变长
	list->size++;
	return ;
}


//删除指定位置的值
void RemoveByPos_LinkList(LinkList* list, int pos)
{
	if (list == NULL || (pos > list->size || pos < 0))
	{
		return;
	}
	LinkNode* pCurrent = (LinkNode*)malloc(sizeof(LinkNode));
	if (pCurrent == NULL)
	{
		return;
	}
	//查找删除节点的前一个结点
	pCurrent = list->head;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}
	//辅助节点
	LinkNode* deleteNode = pCurrent->next;
	pCurrent->next = pCurrent->next->next;
	//释放删除结点的内存
	free(deleteNode);

	return;
}

//获得链表的长度
int Size_LinkList(LinkList* list)
{
	return list->size;
}

//查找
int Find_LinkList(LinkList* list, void* data)
{
	if (list == NULL || data == NULL)
	{
		return -1;
	}
	//遍历查找
	LinkNode* pCurrent = list->head->next;
	int i = 0;
	while (pCurrent!=NULL)
	{
		if (pCurrent->data == data)
		{
			break;
		}
		i++;
		pCurrent = pCurrent->next;
	}
	return i;
}

//返回第一个结点
void* Front_LinkList(LinkList* list)
{
	return list->head->next->data;
}

//释放链表内存
void FreeSpace_LinkList(LinkList* list)
{
	if (list == NULL)
	{
		return;
	}
	//辅助指针变量
	LinkNode* pCurrent = list->head;
	while (pCurrent != NULL)
	{
		//缓存下一个节点
		LinkNode* pNext = pCurrent->next;
		free(pCurrent);
		pCurrent = pNext;
	}
	return;
}

//打印链表结点
void Print_LinkList(LinkList* list, PRINTLINKNODE print)
{
	if (list == NULL)
	{
		return;
	}
	//辅助指针变量
	LinkNode* pCurrent = list->head->next;
	while (pCurrent!=NULL)
	{
		print(pCurrent->data);
		pCurrent = pCurrent->next;
	}
	return;
}
//main.c调用
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"LinkList.h"
//自定义数据类型
typedef struct PERSON
{
	char name[64];
	int age;
	int score;
}Person;

//打印函数
void MyPrint(void* data)
{
	Person* p = (Person*)data;
	printf("Name:%s  Age:%d  Score:%d\n", 
		    p->name, p->age, p->score);
}

int main(void)
{
	//创建链表
	LinkList* list = Init_LinkList();

	//创建数据类型
	Person p1 = { "aaa",18,100 };
	Person p2 = { "bbb",19,90 };
	Person p3 = { "ccc",20,80 };
	Person p4 = { "ddd",21,70 };
	Person p5 = { "eee",22,60 };

	//数据插入链表
	Insert_LinkList(list, 0, &p1);
	Insert_LinkList(list, 0, &p2);
	Insert_LinkList(list, 0, &p3);
	Insert_LinkList(list, 0, &p4);
	Insert_LinkList(list, 0, &p5);
	//打印
	Print_LinkList(list,MyPrint);

	cout << "---------------------" << endl;
	//返回第一个节点
	void* ret = Front_LinkList(list);
	MyPrint(ret);

	cout << "---------------------" << endl;
	RemoveByPos_LinkList(list, 1);
	Print_LinkList(list, MyPrint);
	//销毁链表
	FreeSpace_LinkList(list);
	cout << "---------------------" << endl;	
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_Csyn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值