本文介绍: 待补充

代码上传至gitee中,点击此处查看。

下面是思路的阐述

动态数组实现

dynamicArray.h

#pragma once

#include <iostream&gt;
#include <string&gt;
#include <stdlib.h&gt;
using namespace std;

typedef struct dynamicArray {
	void** pAddr;
	int capacity;
	int size;
}DA;

//dynamic array initialize.
DA* Dynamic_Init(int capacity);

//print int elements.
void myPrintInt(void* data);

//insert new data to dynamic array.If full,double it.
void insert_DynamicArray(DA* array, int pos, void* data);	

//foreach dynamic array.
void foreach_DynamicArray(DA* array, void(myPrintAll)(void*));

//remove elements by position.
void removeByPos_DynamicArray(DA* array, int pos);

//compare int elements.
bool myCompareInt(int* data1, int* data2);

//remove elements by value.
void removeByValue_DynamicArray(DA* array, void* value, bool(*myCompare)(void*, void*));

//destory dynamic array.
void destory_DynamicArray(DA* array);

dynamicArray,cpp

#include "dynamicArray.h"

DA* Dynamic_Init(int capacity) {
	if (capacity < 0) {
		return NULL;
	}

	//结构体放在了堆区
	DA* array = (DA*)malloc(sizeof(DA));
	if (array == NULL) {
		return NULL;
	}

	//结构体的属性也放在了堆区
	array-&gt;pAddr = (void**)malloc(sizeof(void*) * capacity);
	array->capacity = capacity;
	array->size = 0;

	return array;	//返回动态数组地址
}

//create new dynamic array
void insert_DynamicArray(DA* array, int pos, void* data) {
	if (array == NULL) {
		return ;
	}
	if (data == NULL) {
		return ;
	}
	
	//无效位置尾插
	if (pos < 0 || pos >= array->size) {
		//array->pAddr = data;	//错误思路
		pos = array->size;	//位置变化成尾部,而不是在这里直接插入
	}
	

	//如果数组已经满了,那就扩容2倍
	if (array->capacity == array->size) {
		int newCapacity = array->capacity * 2;
		//存放void*类型数据
		void** newSpace = (void**)malloc(sizeof(void*) * newCapacity);
		//将原来动态数组数据拷贝到新的空间下
		memcpy(newSpace, array->pAddr, sizeof(void*) * array->capacity);
		//释放原来的内存空间
		free(array->pAddr);
		//更新指向,指向新的空间
		array->pAddr = newSpace;
		array->capacity = newCapacity;
	}

	//新数据插入数组,原来的元素不断地后移
	for (int i = array->size - 1; i >= pos; i--) {
		array->pAddr[i+1] = array->pAddr[i];
	}

	//新数插进来
	array->pAddr[pos] = data;
	array->size++;
}

//遍历数组
void foreach_DynamicArray(DA* array,void(myPrintAll)(void*)) {
	if (array == NULL) {
		return;
	}
	if (myPrintAll == NULL) {
		return;
	}

	cout << "遍历结果:" << endl;
	for (int i = 0; i < array->size; i++) {
		//cout << array->pAddr[i] << endl;	//错误思路,不确定数据类型
		myPrintAll(array->pAddr[i]);
		//把地址给用户,让用户自己打印
	}
	cout << "遍历完毕" << endl;
}

//按位置删除元素
void removeByPos_DynamicArray(DA* array, int pos) {	//pos指下标
	if (array == NULL) {
		return;
	}
	if (pos<0 || pos>array->size - 1) {	
		return;
	}
	int i = 0;
	for (int i = pos; i < array->size-1; i++) {
		array->pAddr[i] = array->pAddr[i + 1];
	}
	//array->pAddr[i] ='';
	array->size--;

}

//按值删除元素
void removeByValue_DynamicArray(DA* array,void* value,bool(*myCompare)(void*,void*)) {
	if (array == NULL) {
		return;
	}
	if (value == NULL) {
		return;
	}
	for (int i = 0; i < array->size; i++) {
		if (myCompare(array->pAddr[i], value)) {
			removeByPos_DynamicArray(array, i);
			break;
		}
	}
}

void destory_DynamicArray(DA* array) {
	if (array == NULL) {
		return;
	}

	if (array->pAddr != NULL) {
		delete array->pAddr;
		array->pAddr = NULL;
	}
	delete array;
	array = NULL;

	//if (array == NULL &amp;&amp; array->pAddr == NULL) {
	cout << "销毁完毕" << endl;

}

main.cpp

#include "dynamicArray.h"

bool myCompareInt(void* data1,void* data2) {
	int* num1 = (int*)data1;
	int* num2 = (int*)data2;
	return *num1 == *num2 ? true : false;
}

void myPrintInt(void* data) {
	int* num = (int*)data;
	cout << *num << endl;
}


int main() {
	//srand((unsigned)time(NULL));
	/*初始化DA*/
	struct dynamicArray* array = Dynamic_Init(5);
	//cout << "容量:" << array->capacity << ",大小:" << array->size << endl;
	cout << "扩容前的容量:" << array->capacity << endl;
	cout << "------" << endl;

	int arr[20];	 
	for (int i = 0; i < 6; i++) {	 //插入6个元素
		arr[i] = i; 
	}
	insert_DynamicArray(array, 0, &arr[0]);
	insert_DynamicArray(array, 1, &arr[1]);
	insert_DynamicArray(array, 0, &arr[2]);
	insert_DynamicArray(array, -1, &arr[3]);
	insert_DynamicArray(array, 0, &arr[4]);
	insert_DynamicArray(array, 1, &arr[5]);
	cout << "插入完毕" << endl;
	cout << "------" << endl;

	foreach_DynamicArray(array,myPrintInt);  // 4 5 2 0 1 3
	cout << "------" << endl;

	cout << "扩容后的容量:" << array->capacity << endl;
	cout << "------" << endl;

	removeByPos_DynamicArray(array, 2);  //按位置删除元素
	foreach_DynamicArray(array, myPrintInt); //4 5 0 1 3
	cout << "------" << endl;
		
	int* remove_Value = (int*)array->pAddr[0]; //按值删除元素
	removeByValue_DynamicArray(array, remove_Value,myCompareInt);
	foreach_DynamicArray(array, myPrintInt); //5 0 1 3
	cout << "------" << endl;

	destory_DynamicArray(array);
	cout << "------" << endl;

	system("pause");
	return 0;
}
扩容前的容量:5
------
插入完毕
------
遍历结果:
4
5
2
0
1
3
遍历完毕
------
扩容后的容量:10
------
遍历结果:
4
5
0
1
3
遍历完毕
------
遍历结果:
5
0
1
3
遍历完毕
------
销毁完毕
------

静态链表动态链表创建遍历

#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <malloc.h>
using namespace std;
 
struct LinkNode {
	int num;
	struct LinkNode* next;	//指针域
};
 
void test01() {		//静态链表 分配到栈区
	//1、创建结点
	struct LinkNode node1 = { 1,NULL };	//静态链表,放在栈区
	struct LinkNode node2 = { 2,NULL };
	struct LinkNode node3 = { 3,NULL };
	struct LinkNode node4 = { 4,NULL };
	struct LinkNode node5 = { 5,NULL };
	//2、建立关系
	node1.next = &node2;
	node2.next = &node3;
	node3.next = &node4;
	node4.next = &node5;
 
	//3、遍历结点
	struct LinkNode* p = &node1;
	while (p != NULL) {
		cout << p->num << endl;
		p = p->next;
	}
}
 
void test02() {		//动态链表dynamic cnodition linklist 分配到堆区
	struct LinkNode *dnode1 = (struct LinkNode*)malloc(sizeof(struct LinkNode));
	struct LinkNode* dnode2 = (struct LinkNode*)malloc(sizeof(struct LinkNode));
	struct LinkNode* dnode3 = (struct LinkNode*)malloc(sizeof(struct LinkNode));
	struct LinkNode* dnode4 = (struct LinkNode*)malloc(sizeof(struct LinkNode));
	struct LinkNode* dnode5 = (struct LinkNode*)malloc(sizeof(struct LinkNode));
 
	//给数据赋值
	dnode1->num = 1;
	dnode2->num = 2;
	dnode3->num = 3;
	dnode4->num = 4;
	dnode5->num = 5;
	//建立关系
	dnode1->next = dnode2;
	dnode2->next = dnode3;
	dnode3->next = dnode4;
	dnode4->next = dnode5;
	dnode5->next = NULL;
 
	struct LinkNode* p = dnode1;
	while (p) {
		cout << p->num << endl;
		p = p->next;
	}
 
	free(dnode1);
	free(dnode2);
	free(dnode3);
	free(dnode4);
	free(dnode5);
	dnode1 = NULL;		//置空,防止野指针
	dnode2 = NULL;
	dnode3 = NULL;
	dnode4 = NULL;
	dnode5 = NULL;
}
 
int main() {
	test02();
	system("pause");
	return 0;
}

单链表的基本操作

单链表(基本数据类型

本文实现的链表操作包含:

  • 链表初始化(头插法,尾插法)
  • 遍历链表
  • 链表插入结点(按位置, 按值)
  • 链表结点删除(按位置, 按值)
  • 清空链表
  • 销毁链表
  • 链表反转
  • 求链表结点个数

LinkList.h

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

typedef struct LinkNode {
	int num;
	struct LinkNode* next;
}LNode,*LinkList;

LNode* initLinkList();	//初始化链表

void foreach_LinkList(struct LinkNode* pHead);  //遍历链表

void insertLinkList(LNode* pHeader, int old_Val, int new_Val);//参数:插入哪个链表?在old val 前 插入 new val

void delete_LinkList(LNode* pHeader, int val);	//删除元素

void clear_LinkList(LNode* pHeader);	//清空链表

void destroy_LinkList(LNode* pHeader);	//销毁链表


void insertByPos_LinkList(LNode* pHeader, int pos, int val);

void deleteByPos_LinkList(LNode* pHeader, int pos);

void reverse_LinkList(LNode* pHeader);		//逆序


int size_LinkList(LNode* pHeader);	//链表结点个数

LinkList.cpp

#include "LinkList.h"


//初始化链表
LNode* initLinkList() { //返回节点的指针
	//创建节点
	LNode* pHeader = (LNode*)malloc(sizeof(LNode));
	//判断分配内存是否成功?
	if (pHeader == NULL) {		//头结点是否有问题?有问题就不用再插了
		return NULL;
	}

	int val = -1;
	//初始化节点
	pHeader->num = -1;	//头结点不维护数据域 写不写都可以
	pHeader->next = NULL;
	//新建一个结点  记录尾结点的位置,方便 尾插法
	LNode* pTail = pHeader;
	//新建一个结点  记录前面结点的位置,方便 头插法
	struct LinkNode* pFront = pHeader;

	while (1) {
		//用户插入几个结点,如果输入的是-1,代表插入结束
		cin >> val;
		if (val != -1) {
			//尾插法
			struct LinkNode* newNode = new struct LinkNode();
			pTail->next = newNode;
			newNode->num = val;
			newNode->next = NULL;
			pTail = newNode;

			//前插法
			/*struct LinkNode* newNode = new struct LinkNode();
			newNode->num = val;
			newNode->next = pFront->next;
			pFront->next = newNode;*/
		}
		else {
			cout << "结束" << endl;
			break;
		}
	}

	return pHeader;
}


void foreach_LinkList(LNode* pHeader) {		//遍历链表 头结点地址指代表
	if (pHeader == NULL) {
		return;
	}
	struct LinkNode* p = pHeader->next;	//指向第一个有真实数据节点
	while (p != NULL) {
		cout << p->num << endl;
		p = p->next;
	}
}

//插入结点   
void insertLinkList(LNode* pHeader, int old_Val, int new_Val)//参数:插入哪个链表?在old val 前 插入 new val
{
	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;
	
	while (p->next != NULL) {
		if (p->next->num == old_Val) {	/*关键就是指针在old_Val的前一个
			结点时停下,才可以插入*/
			LNode* newNode = new LNode();
			newNode->num = new_Val;
			newNode->next = p->next;
			p->next = newNode;
			cout << "插入成功" << endl;
			/*delete newNode;
			newNode = NULL;    
			//即使函数结束,节点也将一直存在,所以不能是放掉*/

			break;
		}
		else {
			p = p->next;
		}

	}
	if (p->next == NULL) {		//说明没有old_Val,在尾部插入
		LNode* newNode = new LNode();
		newNode->num = new_Val;
		newNode->next = p->next;
		p->next = newNode;
		//cout << "插入失败,old_Val不存在" << endl;
		cout << "插入成功(无old_Val,插在尾部)" << endl;
		/*delete newNode;
		newNode = NULL;*/
	}
}



void delete_LinkList(LNode *pHeader,int val) {	//删除元素
	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;//不喜欢直接用头指针,新定义一个指针
	while (p->next != NULL) {
		if (p->next->num == val) {
			LNode* delNode = p->next;
			p->next = p->next->next;
			delete delNode;
			delNode = NULL;
			cout << "删除成功" << endl;
			break;
		}
		else {
			p = p->next;
		}
	}
	if (p->next == NULL) {
		cout << "链表中没有此元素" << endl;
	}
}

/*清空链表与销毁链表:
清空操作头结点,链表还可以使用;
销毁操作头结点,链表不可以再次使用了*/
void clear_LinkList(LNode *pHeader) {	//清空链表
	if (pHeader == NULL) {
		return;
	}
	LNode* del = pHeader->next;
	LNode* del_Next = del;
	pHeader->next = NULL;	//防止野指针
	while (del != NULL) {
		del_Next = del->next;
		delete(del);
		del = NULL;
		del = del_Next;

	}

	cout << "清空完毕" << endl;
}


void destroy_LinkList(LNode* pHeader) {	//销毁链表
	if (pHeader == NULL) {
		return;
	}

	clear_LinkList(pHeader);
	delete pHeader;
	pHeader = NULL;
	cout << "销毁完毕" << endl;
}

void insertByPos_LinkList(LNode* pHeader, int pos, int val)  //pos:指下标
{
	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;
	int flag = 0;

	while (p->next != NULL && flag < pos-1) {
			p = p->next;
			flag++;
	}

	if (flag == pos-1) {
		LNode *newNode = new LNode();   //动态
		newNode->next = p->next;
		p->next = newNode;
		newNode->num = val;

		//LNode newNode = {0,NULL};			//静态
		//newNode.next = p->next;
		//p->next = &newNode;
		//newNode.num = val;
		cout << "在pos = " << pos << "位置插入了val = " << val << endl;
	}
	else {
		cout << "插入的pos有误" << endl;
		return;
	}
}

void deleteByPos_LinkList(LNode* pHeader, int pos)
{

	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;
	int flag = 0;

	while (p->next != NULL && flag < pos - 1) {
		p = p->next;
		flag++;
	}

	if (flag == pos - 1) {
		LNode* del = p->next;
		p->next = del->next;
		delete del;
		del->next == NULL;
		cout << "删除了pos = " << pos << "的元素" << endl;
	}
	else {
		cout << "删除的pos有误" << endl;
		return;
	}
}

//利用三个辅助指针,实现链表反转
void reverse_LinkList(LNode* pHeader)		//链表反转
{
	if (pHeader == NULL){
		return;
		}
	LNode* pprev = NULL;
	LNode* pcur = pHeader->next;
	LNode* pnext = NULL;
	while (pcur!=NULL) {
		pnext = pcur->next;
		pcur->next = pprev;

		pprev = pcur;
		pcur = pnext;
	}

	pHeader->next = pprev;

}

int size_LinkList(LNode* pHeader) {
	if (pHeader == NULL) {
		return -1;
	}
	int num = 0;
	LNode* pflag = pHeader->next;
	while (pflag != NULL) {
		num++;
		pflag= pflag->next;
	}
	return num;
}

main.cpp

#include "LinkList.h"


//初始化链表
LNode* initLinkList() { //返回头节点的指针
	//创建头节点
	LNode* pHeader = (LNode*)malloc(sizeof(LNode));
	//判断分配内存是否成功?
	if (pHeader == NULL) {		//头结点是否有问题?有问题就不用再插了
		return NULL;
	}

	int val = -1;
	//初始化头节点
	pHeader->num = -1;	//头结点不维护数据域 写不写都可以
	pHeader->next = NULL;
	//新建一个结点  记录尾结点的位置,方便 尾插法
	LNode* pTail = pHeader;
	//新建一个结点  记录前面结点的位置,方便 头插法
	struct LinkNode* pFront = pHeader;

	while (1) {
		//用户插入几个结点,如果输入的是-1,代表插入结束
		cin >> val;
		if (val != -1) {
			//尾插法
			struct LinkNode* newNode = new struct LinkNode();
			pTail->next = newNode;
			newNode->num = val;
			newNode->next = NULL;
			pTail = newNode;

			//前插法
			/*struct LinkNode* newNode = new struct LinkNode();
			newNode->num = val;
			newNode->next = pFront->next;
			pFront->next = newNode;*/
		}
		else {
			cout << "结束" << endl;
			break;
		}
	}

	return pHeader;
}


void foreach_LinkList(LNode* pHeader) {		//遍历链表 头结点地址指代表
	if (pHeader == NULL) {
		return;
	}
	struct LinkNode* p = pHeader->next;	//指向第一个有真实数据的节点
	while (p != NULL) {
		cout << p->num << endl;
		p = p->next;
	}
}

//插入结点   
void insertLinkList(LNode* pHeader, int old_Val, int new_Val)//参数:插入哪个链表?在old val 前 插入 new val
{
	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;
	
	while (p->next != NULL) {
		if (p->next->num == old_Val) {	/*关键就是指针在old_Val的前一个
			结点时停下,才可以插入*/
			LNode* newNode = new LNode();
			newNode->num = new_Val;
			newNode->next = p->next;
			p->next = newNode;
			cout << "插入成功" << endl;
			/*delete newNode;
			newNode = NULL;    
			//即使函数结束,节点也将一直存在,所以不能是放掉*/

			break;
		}
		else {
			p = p->next;
		}

	}
	if (p->next == NULL) {		//说明没有old_Val,在尾部插入
		LNode* newNode = new LNode();
		newNode->num = new_Val;
		newNode->next = p->next;
		p->next = newNode;
		//cout << "插入失败,old_Val不存在" << endl;
		cout << "插入成功(无old_Val,插在尾部)" << endl;
		/*delete newNode;
		newNode = NULL;*/
	}
}



void delete_LinkList(LNode *pHeader,int val) {	//删除元素
	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;//不喜欢直接用头指针,新定义一个指针
	while (p->next != NULL) {
		if (p->next->num == val) {
			LNode* delNode = p->next;
			p->next = p->next->next;
			delete delNode;
			delNode = NULL;
			cout << "删除成功" << endl;
			break;
		}
		else {
			p = p->next;
		}
	}
	if (p->next == NULL) {
		cout << "链表中没有此元素" << endl;
	}
}

/*清空链表与销毁链表:
清空不操作头结点,链表还可以使用;
销毁操作头结点,链表不可以再次使用了*/
void clear_LinkList(LNode *pHeader) {	//清空链表
	if (pHeader == NULL) {
		return;
	}
	LNode* del = pHeader->next;
	LNode* del_Next = del;
	pHeader->next = NULL;	//防止野指针
	while (del != NULL) {
		del_Next = del->next;
		delete(del);
		del = NULL;
		del = del_Next;

	}

	cout << "清空完毕" << endl;
}


void destroy_LinkList(LNode* pHeader) {	//销毁链表
	if (pHeader == NULL) {
		return;
	}

	clear_LinkList(pHeader);
	delete pHeader;
	pHeader = NULL;
	cout << "销毁完毕" << endl;
}

void insertByPos_LinkList(LNode* pHeader, int pos, int val)  //pos:指下标
{
	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;
	int flag = 0;

	while (p->next != NULL && flag < pos-1) {
			p = p->next;
			flag++;
	}

	if (flag == pos-1) {
		LNode *newNode = new LNode();   //动态
		newNode->next = p->next;
		p->next = newNode;
		newNode->num = val;

		//LNode newNode = {0,NULL};			//静态
		//newNode.next = p->next;
		//p->next = &newNode;
		//newNode.num = val;
		cout << "在pos = " << pos << "位置插入了val = " << val << endl;
	}
	else {
		cout << "插入的pos有误" << endl;
		return;
	}
}

void deleteByPos_LinkList(LNode* pHeader, int pos)
{

	if (pHeader == NULL) {
		return;
	}
	LNode* p = pHeader;
	int flag = 0;

	while (p->next != NULL && flag < pos - 1) {
		p = p->next;
		flag++;
	}

	if (flag == pos - 1) {
		LNode* del = p->next;
		p->next = del->next;
		delete del;
		del->next == NULL;
		cout << "删除了pos = " << pos << "的元素" << endl;
	}
	else {
		cout << "删除的pos有误" << endl;
		return;
	}
}

//利用三个辅助指针,实现链表反转
void reverse_LinkList(LNode* pHeader)		//链表反转
{
	if (pHeader == NULL){
		return;
		}
	LNode* pprev = NULL;
	LNode* pcur = pHeader->next;
	LNode* pnext = NULL;
	while (pcur!=NULL) {
		pnext = pcur->next;
		pcur->next = pprev;

		pprev = pcur;
		pcur = pnext;
	}

	pHeader->next = pprev;

}

int size_LinkList(LNode* pHeader) {
	if (pHeader == NULL) {
		return -1;
	}
	int num = 0;
	LNode* pflag = pHeader->next;
	while (pflag != NULL) {
		num++;
		pflag= pflag->next;
	}
	return num;
}
10 20 30 -1
结束
------
10
20
30
------
插入成功
插入成功
插入成功(无old_Val,插在尾部)
插入成功
插入后的遍历:
10
1000
2000
20
3000
30
500
------
结点个数:
7
反转后的遍历:
500
30
3000
20
2000
1000
10
------
删除成功
删除成功
删除成功
删除后的遍历:
500
30
20
10
------
在pos = 2位置插入了val = 666
500
666
30
20
10
------
反转后的遍历:
10
20
30
666
500
------
删除的pos有误
10
20
30
666
500
------
清空完毕
清空后的遍历:
------
清空完毕
销毁完毕
------

问题及解决

1、插入、删除 使用两个指针操作 的方法 操作一下这个

2、存在内存泄露问题

3、断言错误

在这里插入图片描述
在这里插入图片描述

错误原因是 静态变量是局部变量,占用栈空间 ,函数体内执行完后就释放掉了; 而链表还需要用的.修改动态定义newNode 后 ,就可以正常运行了.

​​在这里插入图片描述

单链表(任意数据类型

Linklist.h

#pragma once

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

struct LinkNode {
	void* data;
	struct LinkNode* next;
};

struct LList {
	struct LinkNode pHeader;	//头结点
	int m_size;	//链表长度
};

typedef void* LinkList;	//用void*隐藏pHeader和m_size,用户无法直接操作pHeader和m_size属性 
//在底层会把void*转成LinkList类型

LinkList init_LinkList();	//初始化链表

//插入元素
void insert_LinkList(LinkList list, int pos, void* data);

//遍历链表
void foreach_LinkList(LinkList list, void(*myPrint)(void*));

//按位置删除元素
void deleteByPos_LinkList(LinkList list, int pos);

//按值删除元素
void deleteByValue_LinkList(LinkList list, void* value, bool(*myCompare)(void*, void*));

//比较两个元素是否相同
bool myCompareInt(void* data1, void* data2);

//清空链表
void declear_LinkList(LinkList list);

//返回链表元素个数
int size_LinkList(LinkList list);

//销毁链表
void destory_LinkList(LinkList list);

Linklist.cpp

#include "Linklist.h"

LinkList init_LinkList() {
	struct LList* myList = (struct LList*)malloc(sizeof(struct LList));

	if (myList == NULL) {
		return NULL;
	}

	myList->pHeader.data = NULL;
	myList->pHeader.next = NULL;
	myList->m_size = 0;

	return myList;
}

void insert_LinkList(LinkList list, int pos, void* data) {
	//为什么list == NULL?他是在堆区吗  答: LinkList就是void*
	if (list == NULL) {
		return;
	}

	if (data == NULL) {
		return;
	}

	struct LList* myList = (struct LList*)list;  //将list还原成struct LList类型 ,就可以.引用
	if (pos<0 || pos>myList->m_size) {	//pos指下标
		pos = myList->m_size;	//无效位置尾插
	}

	struct LinkNode* pCurrent = &myList->pHeader;
	
	for (int i = 0; i < pos; i++) { 
		pCurrent = pCurrent->next;
	}
	struct LinkNode* newNode = (struct LinkNode*)malloc(sizeof(struct LinkNode));

	newNode->data = data;
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;

	myList->m_size++;

	cout << "插入完毕" << endl;
}


void foreach_LinkList(LinkList list,void(*myPrint)(void*)) {	//????void *
	if (list == NULL) {
		return;
	}

	struct LList* mylist = (struct LList*)list;
	
	struct LinkNode* pCurrent = mylist->pHeader.next;   //临时结点 
	// mylist->pHeader.next 指的是 头结点 下一个结点 的地址
	// &mylist->pHeader  指的是头结点的地址

	for (int i = 0; i < mylist->m_size; i++) {
		myPrint(pCurrent->data);  //void* 数据不能printf打印,所以把数据域交给用户自己打印 
		pCurrent = pCurrent->next;
	}
	cout << endl;
}

void deleteByPos_LinkList(LinkList list, int pos) {
	if (list == NULL) {
		return;
	}
	//1 2 3 4 5 6 7
	struct LList* mylist = (struct LList*)list;
	if (pos<0 || pos>mylist->m_size - 1) {
		return;
	}

	struct LinkNode* pCurrent = &mylist->pHeader;	
	for (int i = 0; i < pos; i++) {		//待删除结点的前驱结点 
		pCurrent = pCurrent->next;
	}
	struct LinkNode* pDel = pCurrent->next;
	pCurrent->next = pCurrent->next->next;
	
	free(pDel);
	pDel = NULL;
	
	mylist->m_size--;
}


void deleteByValue_LinkList(LinkList list, void* value,bool(*myCompare)(void*,void*)) {
	if (list == NULL) {
		return;
	}
	if (value == NULL) {
		return;
	}

	struct LList* mylist = (struct LList*)list;
	
	struct LinkNode* pPrev = &mylist->pHeader;
	struct LinkNode* pCurrent = pPrev->next;
	for (int i = 0; i < mylist->m_size; i++) {
		//if (*(int*)value == *(int*)pCurrent->data) {
			if(myCompare(value,pCurrent->data)){
			//==不出来的原因是  void*是没有值的
				pPrev->next = pCurrent->next;
				free(pCurrent);
				pCurrent = NULL;
				mylist->m_size--;	//没有这句的话,会在遍历的时候卡几秒钟
				break;

			//int pos = i;
			//deleteByPos_LinkList(mylist, pos);
			//break;		//删了之后应该break,因为此时,pCurrent没指向了
		}

			pPrev = pPrev->next;
			pCurrent = pCurrent->next;
	}
}

void declear_LinkList(LinkList list) {
	if (list == NULL) {
		return;
	}
	struct LList* mylist = (struct LList*)list;
	struct LinkNode* pCurrent = mylist->pHeader.next;
	struct LinkNode* pDel = NULL;
	int size = mylist->m_size;
	for (int i = 0; i < mylist->m_size; i++) {
		pDel = pCurrent;
		pCurrent = pCurrent->next;
		mylist->pHeader.next = pCurrent;
		pDel = NULL;
		size--;
	}
	mylist->m_size = size;
	//cout << size;
	//mylist->m_size = 0;
	if (mylist->pHeader.next == NULL) {
		cout << "清空完毕" << endl;
	}
}


int size_LinkList(LinkList list) {
	if (list == NULL) {
		return -1;
	}
	struct LList* mylist = (struct LList*)list;
	return mylist->m_size;
}

void destory_LinkList(LinkList list) {
	if (list == NULL) {
		return;
	}
	
	declear_LinkList(list);	//清空链表

	//不需要释放头指针,因为头结点包含在了LList里面
	//struct LList* mylist = (struct LList*)list;
	//struct LinkNode* pHead = &mylist->pHeader;
	//free(pHead);
	//pHead == NULL;	//释放头指针

	free(list);	//释放链表指针
	list = NULL;
	cout << "销毁完毕" << endl;
}


main.cpp

#include "Linklist.h"

void myPrintint(void* data) { //用户自己提供
	//struct Person * p = (struct Person *)data; 
	int* value = (int*)data;
	printf("%d",*value);
}

bool myCompareInt(void* data1, void* data2) {
	int* value1 = (int*)data1;
	int* value2 = (int*)data2;

	return *value1 == *value2 ? true : false;
}

int main() {
	int a[5] = { 5,4,3,2,1 };

	LinkList list = init_LinkList(); 
	//cout << "链表长度:" << list-> << endl;
	insert_LinkList(list, 0, &a[0]);
	insert_LinkList(list, 1, &a[1]);
	insert_LinkList(list, -1, &a[2]);
	insert_LinkList(list, 0, &a[3]);
	insert_LinkList(list, -1, &a[4]);

	struct LList* mylist = (struct LList*)list;
	struct LinkNode* pCurrent = &mylist->pHeader;
	//   2 5 4 3 1
	foreach_LinkList(list, myPrintint);


	deleteByPos_LinkList(list, 0);
	foreach_LinkList(list, myPrintint);
	int c = 4;
	deleteByValue_LinkList(list, &c,myCompareInt);
	foreach_LinkList(list, myPrintint);

	declear_LinkList(list);
	foreach_LinkList(list, myPrintint);
	destory_LinkList(list);
	return 0;
}
插入完毕
插入完毕
插入完毕
插入完毕
插入完毕
25431
5431
531
清空完毕

清空完毕
销毁完毕

队列的基本操作

顺序

seqQueue.h

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

#define MAX 1024

struct SQueue{		
	void* data[MAX];
	int m_Size;
};

struct Person {    main函数队列测试用的结构体数组
	char name[64];
	int age;
};

typedef void* seqQueue;

struct SQueue* init_SeqQueue();	//初始化顺序队列

void push_SeqQueue(seqQueue queue, void* value); //入队操作

void pop_SeqQueue(seqQueue queue);	//出队操作

void* top_SeqQueue(seqQueue queue);	//查询队头元素

int size_SeqQueue(seqQueue queue); //队列长度

int isEmpty_SeqQueue(seqQueue queue);	//队列是否为空

void clear_SeqQueue(seqQueue queue);	//清空队列

void destroy_SeqQueue(seqQueue queue);	//销毁队列

seqQueue.cpp

#include "seqQueue.h"



struct SQueue* init_SeqQueue() {
	//struct SQueue* myQueue = (struct SQueue*)malloc(sizeof(void*) * MAX);
	struct SQueue* myQueue = (struct SQueue*)malloc(sizeof(struct SQueue));
	if (myQueue == NULL) {
		return NULL;
	}
	//memset(myQueue->data[MAX], '', MAX);	//?把
	memset(myQueue->data, '', sizeof(void*) * MAX);
	myQueue->m_Size = 0;

	return myQueue;
}

void push_SeqQueue(seqQueue queue,void* value){
	if (queue == NULL) {
		return;
	}

	struct SQueue* myQueue = (struct SQueue*)queue;
	if (value == NULL) {
		return;
	}

	if (myQueue->m_Size == MAX) {
		return;
	}
	int i = 0;
	for (i = 0; i < MAX && myQueue->data[i] == (void*)''; i++);//栈是怎么实现的
	--i;
	myQueue->data[i] = value;
	cout << "入队 - 姓名:" << ((struct Person*)value)->name << ",年龄:" << 
		((struct Person*)value)->age <<  endl;
	myQueue->m_Size++;
}

void pop_SeqQueue(seqQueue queue) {		//队头出队   MAX
	if (queue == NULL) {
		return;
	}
	struct SQueue* myQueue = (struct SQueue*)queue;

	if (myQueue->m_Size == 0) {
		return;
	}
	int i = 0;
			//出栈后,队列会自动向前吗:不是循环队列把
	for (i = MAX-1; i >=0 && myQueue->data[i] == (void*)''; i--);//栈是怎么实现的
	
	myQueue->data[i] = (void*)'';
	myQueue->m_Size--;
}

void* top_SeqQueue(seqQueue queue) {
	if (queue == NULL) {
		return NULL;
	}
	struct SQueue* myQueue = (struct SQueue*)queue;

	if (myQueue->m_Size == 0) {
		return NULL;
	}
	int i = 0;
	for (i = MAX - 1; i >= 0 && myQueue->data[i] == (void*)''; i--);//栈是怎么实现的
	return myQueue->data[i];
}


int size_SeqQueue(seqQueue queue) {
	if (queue == NULL) {
		return -1;
	}
	struct SQueue* myQueue = (struct SQueue*)queue;
	return myQueue->m_Size;
}

int isEmpty_SeqQueue(seqQueue queue) {
	if (queue == NULL) {
		return -1;
	}
	struct SQueue* myQueue = (struct SQueue*)queue; 
	return (myQueue->m_Size == 0) ? 1 : 0;
}

void clear_SeqQueue(seqQueue queue) {
	if (queue == NULL) {
		return;
	}
	struct SQueue* myQueue = (struct SQueue*)queue;

	for (int i = 0; i < myQueue->m_Size; i++) {
		myQueue->data[i] = (void*)'';
	}
	cout << "清空队列完毕" << endl;
}

void destroy_SeqQueue(seqQueue queue) {
	if (queue == NULL) {
		return;
	}
	free(queue);
	queue = NULL;
	cout << "队列销毁完毕" << endl;
}

main.cpp

#include "seqQueue.h"



int main() {
	struct Person p1 = { "aaa",10 };
	struct Person p2 = { "bbb",20 };
	struct Person p3 = { "ccc",30 };
	struct Person p4 = { "ddd",40 };
	struct Person p5 = { "eee",50 };

	struct SQueue* queue = init_SeqQueue();	//初始化
	cout << "------" << endl;
	push_SeqQueue(queue, &p1);
	cout << "队列元素个数:" << queue->m_Size << endl;
	push_SeqQueue(queue, &p2);
	push_SeqQueue(queue, &p3);
	push_SeqQueue(queue, &p4);
	cout << "队列元素个数:" << queue->m_Size << endl;
	push_SeqQueue(queue, &p5);
	cout << "------" << endl;

	for (int i = 0; i < 5; i++) {
		struct Person* p = (struct Person*)top_SeqQueue(queue);
		pop_SeqQueue(queue);
		cout << "出队 - 姓名:" << p->name << ",年龄:" << p->age << endl;
	}

	cout << "------" << endl;
	clear_SeqQueue(queue);
	cout << "------" << endl;
	cout << (isEmpty_SeqQueue(queue) ? "队列是空的" : "队列非空") << endl;

	cout << "------" << endl;

	destroy_SeqQueue(queue);

	return 0;
}
------
入队 - 姓名:aaa,年龄:10
队列元素个数:1
入队 - 姓名:bbb,年龄:20
入队 - 姓名:ccc,年龄:30
入队 - 姓名:ddd,年龄:40
队列元素个数:4
入队 - 姓名:eee,年龄:50
------
出队 - 姓名:aaa,年龄:10
出队 - 姓名:bbb,年龄:20
出队 - 姓名:ccc,年龄:30
出队 - 姓名:ddd,年龄:40
出队 - 姓名:eee,年龄:50
------
清空队列完毕
------
队列是空的
------
队列销毁完毕

链队

LinkQueue.h

#pragma once
#include <iostream>
#include <stdlib.h>
using namespace std;


struct QueueNode {
	struct QueueNode* next;	//只存放下一节点的地址
};

struct LQueue {
	struct QueueNode pHeader;	//头结点
	int m_Size;	//大小
	struct QueueNode* pTail;	//尾指针 ---- 队尾
};

typedef void* LinkQueue;	//链队	把void*封装成LinkQueue,实际在函数体内可以强转

struct Person	//自定义结构体类型用于main函数测试
{
	void* node;
	char name[64];
	int age;
};

LinkQueue init_LinkQueue();	//初始化链队

void push_LinkQueue(LinkQueue queue, void* value);	//入队

void pop_LinkQueue(LinkQueue queue);	//出队

struct QueueNode* tail_LinkQueue(LinkQueue queue);	//返回队尾元素

struct QueueNode* head_LinkQueue(LinkQueue queue);	//返回队头元素

int size_LinkQueue(LinkQueue queue);	//返回链队的长度

int isEmpty_LinkQueue(LinkQueue queue);	//返回链队是否为空

void destroy_LinkQueue(LinkQueue queue);	//销毁链队


LinkQueue.cpp

#include "LinkQueue.h"

LinkQueue init_LinkQueue() {	//返回这种类型用户
	
	struct LQueue * queue = (struct LQueue*)malloc(sizeof(struct LQueue));
	if (queue == NULL) {
		return NULL;
	}
	
	queue->pHeader.next = NULL;
	queue->m_Size = 0;
	queue->pTail = &queue->pHeader;
	cout << "初始化完毕" << endl;
	return queue;
}

void push_LinkQueue(LinkQueue queue,void* value) {
	if (queue == NULL) {
		return;
	}
	if (value == NULL) {
		return;
	}
	struct LQueue* myqueue = (struct LQueue*)queue;
	struct QueueNode* newNode = (struct QueueNode*)value;
	newNode->next = NULL;
	myqueue->pTail->next = newNode;
	myqueue->pTail = newNode;
	myqueue->m_Size++;
}

void pop_LinkQueue(LinkQueue queue) {
	if (queue == NULL) {
		return;
	}
	struct LQueue* myqueue = (struct LQueue*)queue;
	if (myqueue->m_Size == 0) {
		return;
	}
	if (myqueue->m_Size == 1) {
		myqueue->pTail = &myqueue->pHeader;
	}
	myqueue->pHeader.next = myqueue->pHeader.next->next;
	
	myqueue->m_Size--;
}

struct QueueNode* tail_LinkQueue(LinkQueue queue) {
	if (queue == NULL) {
		return NULL;
	}
	struct LQueue* myqueue = (struct LQueue*)queue;
	if (myqueue->m_Size == 0) {
		return NULL;
	}

	return myqueue->pTail;
}


struct QueueNode* head_LinkQueue(LinkQueue queue) {
	if (queue == NULL) {
		return NULL;
	}
	struct LQueue* myqueue = (struct LQueue*)queue;
	if (myqueue->m_Size == 0) {
		return NULL;
	}
	
	return myqueue->pHeader.next;
}

int size_LinkQueue(LinkQueue queue) {
	if (queue == NULL) {
		return -1;
	}
	struct LQueue* myqueue = (struct LQueue*)queue;
	return myqueue->m_Size;
}

int isEmpty_LinkQueue(LinkQueue queue) {
	if (queue == NULL) {
		return -1;
	}
	struct LQueue* myqueue = (struct LQueue*)queue;
	return myqueue->m_Size == 0 ? 1 : 0;
}

void destroy_LinkQueue(LinkQueue queue) {
	if (queue == NULL) {
		return;
	}
	free(queue);
	queue = NULL;
}



main.cpp

#include "LinkQueue.h"

void test01()
{
	//初始化队
	LinkQueue myQueue = init_LinkQueue();

	//创建数据
	struct Person p1 = { NULL, "aaa", 10 };
	struct Person p2 = { NULL, "bbb", 20 };
	struct Person p3 = { NULL, "ccc", 30 };
	struct Person p4 = { NULL, "ddd", 40 };
	struct Person p5 = { NULL, "eee", 50 };

	//入队
	push_LinkQueue(myQueue, &p1);
	push_LinkQueue(myQueue, &p2);
	push_LinkQueue(myQueue, &p3);
	push_LinkQueue(myQueue, &p4);
	push_LinkQueue(myQueue, &p5);

	printf("链式存储-- 队的元素个数为:%dn", size_LinkQueue(myQueue));

	while (isEmpty_LinkQueue(myQueue) == 0) //队不为空,查看队顶元素,出队
	{
		struct Person* p = (struct Person*)head_LinkQueue(myQueue);
		printf("队头:姓名:%s 年龄:%dn", p->name, p->age);
		p = (struct Person*)tail_LinkQueue(myQueue);
		printf("队尾:姓名:%s 年龄:%dn", p->name, p->age);
		cout << endl << "---------------" << endl;

		//出队
		pop_LinkQueue(myQueue);
	}

	printf("链式存储-- 队的元素个数为:%dn", size_LinkQueue(myQueue));

	//销毁队
	destroy_LinkQueue(myQueue);
}

int main() {
	test01();
	return 0;
}
初始化完毕
链式存储-- 队的元素个数为:5
队头:姓名:aaa 年龄:10
队尾:姓名:eee 年龄:50

---------------
队头:姓名:bbb 年龄:20
队尾:姓名:eee 年龄:50

---------------
队头:姓名:ccc 年龄:30
队尾:姓名:eee 年龄:50

---------------
队头:姓名:ddd 年龄:40
队尾:姓名:eee 年龄:50

---------------
队头:姓名:eee 年龄:50
队尾:姓名:eee 年龄:50

---------------
链式存储-- 队的元素个数为:0

栈的基本操作

顺序

seqStack.h

#pragma once
#include <stdlib.h>
#include <iostream>
using namespace std;


#define MAX 1024		//栈的最大容量

//没有栈这种类型,写个结构体
struct SStack {
	void* data[MAX];

	int m_Size;
};


struct Person {
	char name[64];
	int age;
};

typedef void* seqStack;		//顺序

seqStack init_SeqStack();	//初始化顺序栈

void push_SeqStack(seqStack stack, void* value);	//入栈

void pop_SeqStack(seqStack stack);	//出栈

void* top_SeqStack(seqStack stack);	//返回栈顶元素

int size_SeqStack(seqStack stack);	//返回顺序栈的元素个数

int isEmpty_SeqStack(seqStack stack);	 //返回是否栈空

void destory_SeqStack(seqStack stack);  //销毁顺序栈

//顺序栈的应用
int isLeft(char ch);
int isRight(char ch);
void print_Error(const char* str, const char* errMsg, const char* pos);

seqStack.cpp

#include "seqStack.h"

//初始化
seqStack init_SeqStack() {
	struct SStack* mystack = (struct SStack*)malloc(sizeof(struct SStack));
	if (mystack == NULL) {
		return NULL;
	}

	memset(mystack->data,0,sizeof(void*)*MAX);

	mystack->m_Size = 0;

	cout << "初始化完成" << endl;
	return mystack;
}

//入栈
void push_SeqStack(seqStack stack,void* value) {
	struct SStack* mystack = (struct SStack*)stack;
	if (mystack == NULL) {
		return;
	}
	if (value == NULL) {
		return;
	}
	if (mystack->m_Size == MAX) {
		return;
	}
	mystack->data[mystack->m_Size] = value;
	cout << "入栈 - 姓名:" << ((struct Person*)value)->name << ",年龄:" << ((struct Person*)value)->age << endl;
	mystack->m_Size++;
}

//出栈
void pop_SeqStack(seqStack stack) {
	struct SStack* mystack = (struct SStack*)stack;
	if (stack == NULL) {
		return;
	}
	if (mystack->m_Size == 0) {
		cout << "栈空,无法出栈" << endl;
		return;
	}
	cout << "出栈 - 姓名:" << ((struct Person*)mystack->data[mystack->m_Size-1])->name << ",年龄:"
		<< ((struct Person*)mystack->data[mystack->m_Size-1])->age << endl;

	mystack->data[mystack->m_Size - 1] = NULL;
	mystack->m_Size--;
}
//返回栈顶
void* top_SeqStack(seqStack stack) {
	if(stack == NULL) {
		return NULL;
	}
	struct SStack* mystack = (struct SStack*)stack;
	if (mystack->m_Size == 0) {
		return NULL;
	}
	return mystack->data[mystack->m_Size - 1];
}

//返回栈大小
int size_SeqStack(seqStack stack) {
	if (stack == NULL) {
		return -1;
	}
	struct SStack* mystack = (struct SStack*)stack;
	return mystack->m_Size;
}

//判断栈是否为空
int isEmpty_SeqStack(seqStack stack) {
	if (stack == NULL) {
		return -1;
	}
	struct SStack* mystack = (struct SStack*)stack;
	return mystack->m_Size == 0 ?  1 : 0;
}

//销毁栈
void destory_SeqStack(seqStack stack) {
	if (stack == NULL) {
		return;
	}
	free(stack);
	stack = NULL;
	//struct SStack* mystack = (struct SStack*)stack;
	//memset(mystack->data,NULL,sizeof(struct SStack) * MAX);
	//mystack->m_Size = 0;
	//free(mystack);
	//mystack = NULL;
	cout << "销毁完毕" << endl;
}

main.cpp

#include "seqStack.h"


void test01() {

	struct Person p1 = { "a",10 };
	struct Person p2 = { "b",20 };
	struct Person p3 = { "c",30 };
	struct Person p4 = { "d",40 };
	struct Person p5 = { "e",50 };
	struct Person p6 = { "f",60 };

	seqStack stack = init_SeqStack();
	cout << "------" << endl;

	push_SeqStack(stack, &p1);
	push_SeqStack(stack, &p2);
	push_SeqStack(stack, &p3);
	push_SeqStack(stack, &p4);
	push_SeqStack(stack, &p5);
	push_SeqStack(stack, &p6);
	cout << "栈的元素个数为:" << size_SeqStack(stack) << endl;
	cout << "入栈完成" << endl;
	cout << "------" << endl;

	while (!isEmpty_SeqStack(stack)) {
		struct Person* p = (struct Person*)top_SeqStack(stack);
		cout << "栈顶 - 姓名:" << p->name << ",年龄:" << p->age << endl;
		pop_SeqStack(stack);
	}
	cout << "栈的元素个数为:" << size_SeqStack(stack) << endl;

	cout << "------" << endl;
	//销毁栈
	destory_SeqStack(stack);
}


void test02() {
	const char* str = "5+5*(6)(+9/3*1-(1+3(";
	const char* p = str;

	seqStack myStack = init_SeqStack();

	while (*p != '') {		//扫描字符串
		if (isLeft(*p)) {
			push_SeqStack(myStack, (void*)p);
		}
		if (isRight(*p)) {
			if (size_SeqStack(myStack) > 0) {
				pop_SeqStack(myStack);
			}
			else {
				print_Error(str, "没匹配到左括号", p);
				break;
			}
		}
		p++;
	}
}

int main() {
	cout << "========↓↓↓栈的基本操作↓↓↓========" << endl;
	test01();	//测试栈的基本操作
	cout << "========↓↓↓栈的应用↓↓↓========" << endl;
	test02();	//测试栈的应用

	return 0;
}
========↓↓↓栈的基本操作↓↓↓========
初始化完成
------
入栈 - 姓名:a,年龄:10
入栈 - 姓名:b,年龄:20
入栈 - 姓名:c,年龄:30
入栈 - 姓名:d,年龄:40
入栈 - 姓名:e,年龄:50
入栈 - 姓名:f,年龄:60
栈的元素个数为:6
入栈完成
------
栈顶 - 姓名:f,年龄:60
出栈 - 姓名:f,年龄:60
栈顶 - 姓名:e,年龄:50
出栈 - 姓名:e,年龄:50
栈顶 - 姓名:d,年龄:40
出栈 - 姓名:d,年龄:40
栈顶 - 姓名:c,年龄:30
出栈 - 姓名:c,年龄:30
栈顶 - 姓名:b,年龄:20
出栈 - 姓名:b,年龄:20
栈顶 - 姓名:a,年龄:10
出栈 - 姓名:a,年龄:10
栈的元素个数为:0
------
销毁完毕
========↓↓↓栈的应用↓↓↓========
初始化完成
入栈 - 姓名:(6)(+9/3*1-(1+3(,年龄:0
出栈 - 姓名:(6)(+9/3*1-(1+3(,年龄:0
入栈 - 姓名:(+9/3*1-(1+3(,年龄:0
入栈 - 姓名:(1+3(,年龄:0
入栈 - 姓名:(,年龄:0

链栈

ListStack.h

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

struct StackNode {
	struct StackNode* next;
};

struct LStack {
	struct StackNode pHeader;
	int m_Size;
};

typedef void* LinkStack;

LinkStack init_LinkStack();	//初始化链栈

void push_LinkStack(LinkStack stack, void* data); //入栈

void pop_LinkStack(LinkStack stack); //出栈

void* top_LinkStack(LinkStack stack); //返回栈顶元素

int size_LinkStack(LinkStack stack); //返回链栈元素个数

int isEmpty_LinkStack(LinkStack stack); //返回是否栈空

void destroy_LinkStack(LinkStack stack); //销毁链栈

ListStack.cpp

#include "ListStack.h"


LinkStack init_LinkStack() {
	struct LStack* myStack = (struct LStack*)malloc(sizeof(struct LStack));

	if (myStack == NULL) {
		return NULL;
	}
	myStack->pHeader.next = NULL;
	myStack->m_Size = 0;

	cout << "初始化完毕" << endl;
	return myStack;		//忘了return,后面销毁的时候会报错
};

void push_LinkStack(LinkStack stack,void* data) {
	if (stack == NULL) {
		return;
	}
	if (data == NULL) {
		return;
	}
	struct LStack* mystack = (struct LStack*)stack;
	struct StackNode* newNode = (struct StackNode*)data;	
	//取出结点的前4/8个字节

	newNode->next = mystack->pHeader.next;
	mystack->pHeader.next = newNode;
	mystack->m_Size++;

}

void pop_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return;
	}
	struct LStack* mystack = (struct LStack*)stack;
	if (mystack->m_Size == 0) {
		return;
	}
	struct StackNode* delNode = (struct StackNode*)mystack->pHeader.next;
	mystack->pHeader.next = delNode->next;
	//free(delNode);
	//delNode = NULL;		//用户的结点,由用户管理
	mystack->m_Size--;
}

void* top_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return NULL;
	}
	struct LStack* mystack = (struct LStack*)stack;
	if (mystack->m_Size == 0) {
		return NULL;
	}
	return mystack->pHeader.next;
}

int size_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return -1;
	}
	struct LStack* mystack = (struct LStack*)stack;

	return mystack->m_Size;
}

int isEmpty_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return -1;
	}
	struct LStack* mystack = (struct LStack*)stack;
	return mystack->m_Size == 0 ? 1 : 0;

}

void destroy_LinkStack(LinkStack stack) {
	if (stack == NULL) {
		return;
	}
	free(stack);
	stack = NULL;			//????
}

main.cpp

#include "ListStack.h"


//测试
struct Person
{
	void* node;
	char name[64];
	int age;
};

void test01()
{
	//初始化栈
	LinkStack myStack = init_LinkStack();

	//创建数据
	struct Person p1 = { NULL, "aaa", 10 };
	struct Person p2 = { NULL, "bbb", 20 };
	struct Person p3 = { NULL, "ccc", 30 };
	struct Person p4 = { NULL, "ddd", 40 };
	struct Person p5 = { NULL, "eee", 50 };

	//入栈
	push_LinkStack(myStack, &p1);
	push_LinkStack(myStack, &p2);
	push_LinkStack(myStack, &p3);
	push_LinkStack(myStack, &p4);
	push_LinkStack(myStack, &p5);

	printf("链式存储-- 栈的元素个数为:%dn", size_LinkStack(myStack));

	while (isEmpty_LinkStack(myStack) == 0) //栈不为空,查看栈顶元素,出栈
	{
		struct Person* p = (struct Person*)top_LinkStack(myStack);
		printf("姓名:%s 年龄:%dn", p->name, p->age);

		//出栈
		pop_LinkStack(myStack);
	}

	printf("链式存储-- 栈的元素个数为:%dn", size_LinkStack(myStack));

	//销毁栈
	destroy_LinkStack(myStack);
}

int main() {
	test01();
	return 0;
}
初始化完毕
链式存储-- 栈的元素个数为:5
姓名:eee 年龄:50
姓名:ddd 年龄:40
姓名:ccc 年龄:30
姓名:bbb 年龄:20
姓名:aaa 年龄:10
链式存储-- 栈的元素个数为:0

链栈遇到的问题

1、pHeader为什么不声明为指针类型
struct LStack {
struct stackNode pHeader; //不用指针类型,因为内存在malloc时已经给它分配好了
int m_Size;
};

如果我们将pHeader声明为struct stackNode*类型,那么在使用链栈时,我们需要额外进行内存的分配和释放操作。每次插入或删除元素时,需要创建新的节点并将指针赋值给pHeader->next,或者释放已经存在的节点。这样会增加复杂性和内存管理的负担。

而将pHeader声明为struct stackNode类型,可以直接将节点作为值存储在pHeader中,不需要进行额外的内存分配和释放操作。这样简化了代码逻辑,并且节省了额外的内存开销。

2.不能重复释放内存空间
重复释放内存可能会导致以下问题

访问非法内存:重复释放后,如果你尝试访问已经释放的内存,那么程序将会访问非法内存,这可能导致崩溃或者其他未定义行为

内存泄漏:如果重复释放了相同的内存块,那么这部分内存将无法被其他程序使用,造成内存泄漏的问题。

程序崩溃:重复释放内存可能会破坏内存管理的数据结构,从而导致程序崩溃或者产生其他无法预料的错误

因此,为了避免这些问题,我们需要确保在释放内存之前,确认该内存块确实需要释放,并且只释放一次。同时,需要避免在释放后继续访问已经释放的内存。

在你的代码中,如果重复调用destroy_LinkStack函数,就会导致重复释放内存,从而产生上述问题。所以在调用destroy_LinkStack函数之后,确保不再使用该内存块,避免重复释放

字符串应用

字符串相加.cpp

//字符串相加

#include <iostream>
#include <string>

using namespace std;

string add(string s1, string s2) {
	int n1 = s1.size();	//长度 
	int n2 = s2.size();
	string res("");

	int temp = 0;
	int i = 0, j = 0;
	for (i = n1 - 1, j = n2 - 1; i >= 0 && j >= 0; i--, j--) {
		int key1 = s1[i] - '0';		//C++字符串能变成字符数组类型吗 
		int key2 = s2[j] - '0';

		if (key1 + key2 + temp < 10) {
			res += key1 + key2 + temp + '0';
			temp = 0;
		}
		else {
			res += (key1 + key2 + temp) % 10 + '0';
			temp = (key1 + key2 + temp) / 10;
		}
	}

	while (i >= 0) {
		if (temp + s1[i] - '0' < 10) {
			res += s1[i] + temp;
			temp = 0;
			i--;
		}
		else {
			res += (s1[i] - '0' + temp) % 10 + '0';
			temp = (s1[i] - '0' + temp) / 10;
			i--;
		}
	}
	while (j >= 0) {
		if (temp + s2[j] - '0' < 10) {
			res += s2[j] + temp;
			temp = 0;
			j--;
		}
		else {
			res += (s2[j] - '0' + temp) % 10 + '0';
			temp = (s2[j] - '0' + temp) / 10;
			j--;
		}
	}

	if (temp != 0) {
		res += temp + '0';
	}

	int n = res.size();
	int left = 0, right = n - 1;
	while (left < right) {
		auto temp = res[left];
		res[left] = res[right];
		res[right] = temp;
		left++;
		right--;
	}
	return res;
}


int main() {
	cout << add("456", "77") << endl;
	return 0;
}
533

原文地址:https://blog.csdn.net/holoyh/article/details/134658796

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_3040.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注