C语言数据结构——简单易懂的代码大合集

文章目录

    • 写在前面
    • 一、线性表
      • 1.1 线性表的顺序表示(静态分配内存)
      • 1.2 线性表的顺序表示(动态分配内存)
      • 1.3 线性表的链式表示(单链表)

写在前面

  • 代码风格:尽量避免晦涩难懂、适当放弃部分严谨、尽可能简单易懂、非常详细的注释(注释比代码多系列)
  • 受众群体:有初级C语言语法基础的初学者、考前突击本科生、考研者
  • 友情提醒:欢迎善意的建议与修改意见,但拒绝无端的网络暴力,自视清高的大神请右上角×掉

本人才疏学浅,知识有限,难免会出现疏漏或者错误,请大家多多指教

所有代码均可直接拷贝运行,已在VS2017中编译通过

VC++ 6.0版本代码后续我会打包给出下载地址

长期更新,最后更新时间2019-3-17

一、线性表

1.1 线性表的顺序表示(静态分配内存)

// 顺序表,顺序表的操作                            
// 1.定义顺序表(静态分配内存)
// 2.插入、删除、查找、输出到屏幕
#include
#include
#define MaxSize 5
typedef struct {    //顺序表结构体
	int data[MaxSize];  //顺序表数据域的大小为5
	int length;   //顺序表的长度
} SqList;          //顺序表的类型

//因为以下四个函数定义在main函数之后
//所以需要申明这四个函数
bool ListInsert(SqList &L, int i, int e);//插入一个元素到顺序表
bool ListDelete(SqList &L, int i);//从顺序表删除一个元素
int  LocateElem(SqList L, int e);//查找一个元素在顺序表第一次出现的位置
void ListPrint(SqList L);//打印顺序表

int main()
{
	int i = 0;    //i作为循环使用
	SqList L;   //定义一个顺序表结构体L
	L.length = 0; //因为现在还没有插入数据,所以L的长度为0

	//这个while是为了输入数据,每次输入后i++,当i=MaxSize结束输入
	printf("输入%d个元素,每两个之间打空格,完毕后按回车\n",MaxSize);
	while (i < MaxSize)
	{
		scanf_s("%d", &L.data[i]);//输入数据,这里用的scanf_s,等价于scanf
		L.length++;            //每输入一个数据,L的长度增加1
		i++;                   //每次循环i自增1
	}
	//输入完毕后打印L到屏幕
	ListPrint(L);

	//执行插入操作,下面可以自己修改,试试有什么不一样
	printf("在第3个元素前面插入10\n");
	if (ListInsert(L, 3, 10) == true)
		ListPrint(L);

	//执行删除操作,下面可以自己修改,试试有什么不一样
	printf("删除第4个元素\n");
	if (ListDelete(L, 4) == true)
		ListPrint(L);

	//执行查找操作,下面可以自己修改,试试有什么不一样
	printf("查找值为1的元素在L中第一次出现的位置\n");
	printf("值为1的元素在L中第一次出现的位置为%d\n", LocateElem(L, 1));

	return 0;
}

//顺序表插入元素的具体实现
bool ListInsert(SqList &L, int i, int e)
{
	if (i >= L.length + 1 || i < 0)    //先判断i是否为有效值 
		return false;				  //插入失败,返回false
	if (L.length > MaxSize)           //在判断顺序表是否已经满了
		return false;                //插入失败,返回false
	for (int j = L.length; j >= i; j--)    //把第i个之后的数据全部后移一位,可以理解为腾位置
	{
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e;              //腾开位置后将待插入元素e插入到第i个位置
	L.length++;                 //长度增加1
	return true;                //插入成功,返回true
}
//顺序表删除元素的具体实现
bool ListDelete(SqList &L, int i)
{
	if (i >= L.length || i < 1)        //先检查i是否为有效值
		return false;
	for (int j = i; j < L.length; j++)   //开始把被删除的值后面的值前移
	{
		L.data[j - 1] = L.data[j];
	}

	L.length--;                 //长度减少1
	return true;
}
//查找顺序表值为e的元素第一次出现的位置
int LocateElem(SqList L, int e)
{
	for (int i = 0; i < L.length; i++)  //用for循环从第一个位置开始找
	{
		if (L.data[i] == e)         //如果找到了就返回被找到的元素的下标+1
		{
			return i + 1;          //因为下标从0开始算,而我们要找出现的位置所以要+1
		}
	}
	return 0;                    //没有找到就返回0
}
//输出这个线性表
void ListPrint(SqList L) 
{
	int i = 0;
	while (i < L.length && L.data[i] != NULL) //只要满足i小于线性表的长度且i对应的数据不为空就输出该元素
	{
		printf("%d\n", L.data[i]);
		i++;                             //每次循环i自增1
	}
	printf("整个线性表的长度为:");
	printf("%d\n", L.length);             //输出线性表的长度
	printf("------------------------------\n");
}

运行结果
C语言数据结构——简单易懂的代码大合集_第1张图片

1.2 线性表的顺序表示(动态分配内存)

// 顺序表,顺序表的操作                            
// 1.定义顺序表(动态分配内存)
// 2.插入、删除、查找、输出到屏幕
#include
#include
#define InitSize 5       //初始化大小为5

typedef struct {         //定义一个动态分配空间的结构体 顺序表
	int *data;           //int类型指针
	int length;			 //当前尺寸
	int MaxSize=10;      //我设定SqList最大尺寸是10,也就是最多放10个元素
} SqList;

//因为以下四个函数定义在main函数之后
//所以需要申明这四个函数
bool ListInsert(SqList &L, int i, int e);//插入一个元素到顺序表
bool ListDelete(SqList &L, int i);//从顺序表删除一个元素
int  LocateElem(SqList L, int e);//查找一个元素在顺序表第一次出现的位置
void ListPrint(SqList L);//打印顺序表

int main()
{
	int i = 0;    //i作为循环使用
	SqList L;
	L.data=(int*)malloc(sizeof(int)*InitSize);//分配内存空间
	L.length = 0; //因为现在还没有插入数据,所以L的长度为0

	//这个while是为了输入数据,每次输入后i++
	printf("输入%d个元素,每两个之间打空格,完毕后按回车\n", InitSize);
	while ((i < InitSize) && (L.length < L.MaxSize))
	{
		scanf_s("%d", &L.data[i]);//输入数据,这里用的scanf_s,等价于scanf
		L.length++;            //每输入一个数据,L的长度增加1
		i++;                   //每次循环i自增1
	}
	//输入完毕后打印L到屏幕
	ListPrint(L);

	//执行插入操作,下面可以自己修改,试试有什么不一样
	printf("在第3个元素前面插入10\n");
	if (ListInsert(L, 3, 10) == true)
		ListPrint(L);
	//执行删除操作,下面可以自己修改,试试有什么不一样
	printf("删除第4个元素\n");
	if (ListDelete(L, 4) == true)
		ListPrint(L);

	//执行查找操作,下面可以自己修改,试试有什么不一样
	printf("查找值为1的元素在L中第一次出现的位置\n");
	printf("值为1的元素在L中第一次出现的位置为%d\n", LocateElem(L, 1));

	return 0;
}

//顺序表插入元素的具体实现
bool ListInsert(SqList &L, int i, int e)
{
	if (i >= L.length + 1 || i < 0 || L.length >= L.MaxSize)//先判断i是否为有效值,L.length是否超出额定分配的空间
		return false;				  //插入失败,返回false
	//realloc可以动态改变指针指向内存的大小
	//用法是 指针名 =(数据类型*)realloc(要改变内存大小的指针名,新的大小)。
	(int *)realloc(L.data, (L.length + 1) * sizeof(int));
	int *j;
	int *k;
	j = &(L.data[i - 1]);//j指向实际插入的位置
	for (k = &(L.data[L.length-1]); k >= j; k--)    //把第j个之后的数据全部后移一位,可以理解为腾位置
	{
		*(k + 1) = *k;
	}
	*j = e;              //腾开位置后将待插入元素e插入到第j个位置
	L.length++;          //长度增加1
	return true;         //插入成功,返回true
}
//顺序表删除元素的具体实现
bool ListDelete(SqList &L, int i)
{
	if (i >= L.length || i < 1)        //先检查i是否为有效值
		return false;
	int *j = &(L.data[i - 1]);//需要删除的元素位置
	int *k = &(L.data[L.length - 1]);//最后一个元素的位置
	for (; j < k; j++)   //开始把被删除的值后面的值前移
	{
		*(j) = *(j + 1);
	}
	L.length--;                 //长度减少1
	return true;
}
//查找顺序表值为e的元素第一次出现的位置
int LocateElem(SqList L, int e)
{
	for (int i = 0; i < L.length; i++)  //用for循环从第一个位置开始找
	{
		if (L.data[i] == e)         //如果找到了就返回被找到的元素的下标+1
		{
			return i + 1;          //因为下标从0开始算,而我们要找出现的位置所以要+1
		}
	}
	return 0;                    //没有找到就返回0
}
//输出这个线性表
void ListPrint(SqList L)
{
	int i = 0;
	while (i < L.length && L.data[i] != NULL) //只要满足i小于线性表的长度且i对应的数据不为空就输出该元素
	{
		printf("%d\n", L.data[i]);
		i++;                             //每次循环i自增1
	}
	printf("整个线性表的长度为:");
	printf("%d\n", L.length);             //输出线性表的长度
	printf("------------------------------\n");
}

运行结果
C语言数据结构——简单易懂的代码大合集_第2张图片

1.3 线性表的链式表示(单链表)

#include
#include
using namespace std;
//线性表的链式存储又称为单链表,本部分所有代码都是带头结点的操作
typedef struct LNode {         //定义单链表结点类型
	int data;            //数据域
	struct LNode *next;       //指针域
}LNode, *LinkList;             //单链表的定义

//建立链表的2种方法  头插法 尾插法
//1.头插法
LinkList CreatList1() {
	//从表尾到表头逆向建立单链表L,每次都在头结点之后插入
	LinkList L = (LinkList)malloc(sizeof(LNode));  //创建头结点;
	LNode *s; int x;
	L->next = NULL;                       //初始化为NULL
	scanf_s("%d", &x);
	while (x != -1)//当x=-1的时候结束插入
	{
		s = (LNode *)malloc(sizeof(LNode)); //创建新节点
		s->data = x;//数据域赋值
		s->next = L->next;
		L->next = s;
		scanf_s("%d", &x);
	}
	return L;
}
//2.尾插法
LinkList CreatList2()
{
	//从表头到表尾正向建立,每次均在表尾插入元素
	LinkList L = (LinkList)malloc(sizeof(LNode));// 创建头结点
	int x; //输入的数据
	LNode *s; // 指针
	LNode *ss = L;//储尾指针;让尾指针先等于L
	L->next = NULL;
	scanf_s("%d", &x);
	while (x != -1)//当x=-1的时候结束插入
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		ss->next = s;
		ss = s;
		scanf_s("%d", &x);
	}
	ss->next = NULL;//最后一个元素的next为NULL
	return L;
}
//3.插入结点操作
//2个函数  一个是 找到第i个位置的函数,另一个是插入函数
LinkList GetElem(LinkList L, int i)
{
	LNode *p = L;
	while (i-- > 0 && p)
	{
		p = p->next;
	}
	return p;
}
bool Insert(LinkList L, int i, int x)
{
	//检查合法性
	//{}
	LNode *s = (LNode*)malloc(sizeof(LNode));
	s->next = GetElem(L, i - 1)->next;
	GetElem(L, i - 1)->next = s;         //调用返回 第i个位置的函数
	s->data = x;
	return true;
}
//4.删除结点操作
bool Delete(LinkList L, int i)
{
	//检查合法性
	//{}
	LNode *p; //找到的前驱
	LNode *q; //要找的那个
	p = GetElem(L, i - 1);
	q = p->next;
	p->next = q->next;
	free(q);
	return true;

}
//5.求表长度
int GetLength(LinkList L)
{
	if (L->next == NULL)
	{
		return NULL;
	}
	int i = 0;
	LinkList p = L->next;
	while (p != NULL)
	{
		i++;
		p = p->next;
	}
	return i;
}
//6.输出表
void Display(LinkList L)
{
	if (L->next == NULL)
		return;
	LinkList p = L->next;
	while (p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}
int main()
{
	LinkList L = CreatList2();//创建链表,随便输入几个数,输入-1停止输入
	Display(L);//打印表
	printf("表长为:%d\n", GetLength(L));//输出长度

	Insert(L, 1, 3);//在第一个位置前面插入3
	Display(L);//打印表
	printf("表长为:%d\n", GetLength(L));//输出长度

	Delete(L, 2);//删除第二个位置的元素
	Display(L);//打印表
	printf("表长为:%d\n",GetLength(L));//输出长度
}

运行结果
C语言数据结构——简单易懂的代码大合集_第3张图片

更新中…

你可能感兴趣的:(数据结构,C/C++基础知识)