代码上传至gitee中,点击此处查看。
下面是思路的阐述
动态数组的实现
dynamicArray.h
#pragma once#include <iostream>
#include <string>
#include <stdlib.h>
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->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] ='\0';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 && 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 3cout << "------" << endl;cout << "扩容后的容量:" << array->capacity << endl;cout << "------" << endl;removeByPos_DynamicArray(array, 2); //按位置删除元素foreach_DynamicArray(array, myPrintInt); //4 5 0 1 3cout << "------" << endl;int* remove_Value = (int*)array->pAddr[0]; //按值删除元素removeByValue_DynamicArray(array, remove_Value,myCompareInt);foreach_DynamicArray(array, myPrintInt); //5 0 1 3cout << "------" << 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 valvoid 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 7struct 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 1foreach_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 1024struct 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], '\0', MAX); //?\0把memset(myQueue->data, '\0', 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*)'\0'; i++);//栈是怎么实现的--i;myQueue->data[i] = value;cout << "入队 - 姓名:" << ((struct Person*)value)->name << ",年龄:" << ((struct Person*)value)->age << endl;myQueue->m_Size++;
}void pop_SeqQueue(seqQueue queue) { //队头出队 MAXif (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*)'\0'; i--);//栈是怎么实现的myQueue->data[i] = (void*)'\0';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*)'\0'; 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*)'\0';}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("链式存储-- 队的元素个数为:%d\n", size_LinkQueue(myQueue));while (isEmpty_LinkQueue(myQueue) == 0) //队不为空,查看队顶元素,出队{struct Person* p = (struct Person*)head_LinkQueue(myQueue);printf("队头:姓名:%s 年龄:%d\n", p->name, p->age);p = (struct Person*)tail_LinkQueue(myQueue);printf("队尾:姓名:%s 年龄:%d\n", p->name, p->age);cout << endl << "---------------" << endl;//出队pop_LinkQueue(myQueue);}printf("链式存储-- 队的元素个数为:%d\n", 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 != '\0') { //扫描字符串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("链式存储-- 栈的元素个数为:%d\n", size_LinkStack(myStack));while (isEmpty_LinkStack(myStack) == 0) //栈不为空,查看栈顶元素,出栈{struct Person* p = (struct Person*)top_LinkStack(myStack);printf("姓名:%s 年龄:%d\n", p->name, p->age);//出栈pop_LinkStack(myStack);}printf("链式存储-- 栈的元素个数为:%d\n", 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