这是学习C++的数据结构的第一个笔记,留着自己今后忘了的时候再看看吧
#include <iostream>
using namespace std;
// 定义一个打印回调指针,由使用者实现
typedef void(*PRINTLINKLIST)(void*);
// 链表节点
typedef struct LINKNODE
{
void* data; //指向链表上的数据
struct LINKNODE* next; //指向下一个节点
LINKNODE() {
data = nullptr; //数据指向空
next = nullptr; //指向下一个空节点
}
}LinkNode;
typedef struct LINKLIST
{
LinkNode* head; //链表表头
int size; //链表节点数目(除去头节点)
LINKLIST() {
head = nullptr;
size = 0;
}
}LinkList;
// 初始化链表
LinkList* initLinkList()
{
LinkList* pList = new LinkList;
// 创建一个头节点
pList->head = new LinkNode;
return pList;
}
//插入数据
bool insertNode(LinkList* pList, int pos, void* pData)
{
if (nullptr == pList || nullptr == pData)
return false;
// 如果插入的位置大于链表节点数,那么就把节点插入到链表最后
if (pList->size < pos)
pos = pList->size;
// 创建一个新的节点并存放数据
LinkNode* pNewNode = new LinkNode;
pNewNode->data = pData;
// 循环找到指定节点位置的前一个位置
LinkNode* pCurNode = pList->head;
for (int i = 0; i < pos; ++i)
pCurNode = pCurNode->next;
// 让新的节点的下一个节点指向找到的节点的下一个节点
pNewNode->next = pCurNode->next;
// 再让找到的节点下一个节点指向新的节点
pCurNode->next = pNewNode;
//链表长度增加1
pList->size++;
return true;
}
int qureyNode(LinkList* pList, void *pData)
{
int pos = 0;
if (nullptr == pList || nullptr == pData || 0 == pList->size)
return -1;
// 拿到第一个数据节点
LinkNode* pCurNode = pList->head->next;
for (int i = 0; i < pList->size; ++i)
{
// 如果是查询的数据就跳槽循环
if (pData == pCurNode->data)
break;
// 否则就继续查找
pCurNode = pCurNode->next;
pos++;
}
return pos;
}
//反转链表
void reversalList(LinkList *pList)
{
if (nullptr == pList || 0 == pList->size)
return;
// 当前第一个数据节点
LinkNode* pCurNode = pList->head->next;
// 当前节点的后继
LinkNode* pPreNode = nullptr;
// 当前节点的前驱
LinkNode* pSucNode = nullptr;
// 可以理解为学生时期排队后向后转的场景
while (pCurNode)
{
// 先获取到当前节点的后继
pPreNode = pCurNode->next;
// 再把当前节点的后继改为当前节点的前驱(反转)
pCurNode->next = pSucNode;
// 反转后把后继指向当前节点(移动指针)
pSucNode = pCurNode;
// 移动完成后把当前节点改为当前节点的后继也就是pPreNode(移动指针)
pCurNode = pPreNode;
// 接下来就把当前指针的前驱改为当前指针的后继 也就是第一步(循环)
}
// 当循环到最后时,pCurNode与pPreNode都指向NULL,此时pCurNode的后继也就是原来最后一个节点
// 目前就成为反转过后的第一个节点,所以就让表头指向pSucNode就完成转换了
pList->head->next = pSucNode;
}
bool deleteNode(LinkList* pList, int pos)
{
if (nullptr == pList || pos >= pList->size)
return false;
// 定位到删除节点的前一个节点
LinkNode* pCurNode = pList->head;
for (int i = 0; i < pos; ++i)
pCurNode = pCurNode->next;
// 待删除节点
LinkNode *pDelNode = pCurNode->next;
pCurNode->next = pDelNode->next;
// 删除节点(这里只是删除链表节点 而不是真正的删除数据)
delete pDelNode;
pDelNode = nullptr;
// 链表节点数减一
pList->size--;
return true;
}
void printLinkList(LinkList* pList, PRINTLINKLIST print)
{
if (nullptr == pList)
return;
// 定位到删除节点
LinkNode* pCurNode = pList->head->next;
for (int i = 0; i < pList->size; ++i)
{
// 回调打印函数
print(pCurNode->data);
// 循环下一个节点
pCurNode = pCurNode->next;
}
}
struct Student
{
char name[64];
int age;
int code;
};
void myPrint(void *data)
{
Student* p = (Student*)data;
cout << "Name:" << p->name << " age:" << p->age << " code:" << p->code << endl;
}
int main()
{
Student st1, st2, st3, st4, st5;
st1 = { "A", 15, 96 };
st2 = { "B", 16, 82 };
st3 = { "C", 18, 55 };
st4 = { "D", 17, 69 };
st5 = { "E", 19, 89 };
// 创建链表
LinkList* pList = initLinkList();
insertNode(pList, 0, &st1);
insertNode(pList, 1, &st2);
insertNode(pList, 2, &st3);
insertNode(pList, 3, &st4);
insertNode(pList, 4, &st5);
// 打印
printLinkList(pList, myPrint);
cout << "========================" << endl;
// 反转链表
reversalList(pList);
printLinkList(pList, myPrint);
int pos = qureyNode(pList, &st3);
if (-1 != pos) {
deleteNode(pList, pos);
cout << "=====成功删除节点:" << pos + 1 << "=====" << endl;
}
printLinkList(pList, myPrint);
system("pause");
return 0;
}
运行结果: