心血来潮又实现了一遍单链表,加深了下对链式存结构的理解。
头结点:为了操作方便,在单链表的第一个结点之前附加一个结点,称为头结点。头结点的数据域可以存储数据标题、表长等信息,也可以不存储任何信息,其指针域存储第一个结点的首地址
头插法:将每次插入的新结点放在头结点之后,其特点是读入的数据顺序与线性表的逻辑顺序正好相反
尾插法:将每次插入的新结点放在链表的尾部(链表中结点的顺序与输入的顺序一致)
SingleLink.h
#pragma once
#include <string>
#include <iostream>
using namespace std;
// 商品信息结构体
typedef struct GoodsInfo
{
char chName[20];
int iPrice;
GoodsInfo* pNext;
}STGoodsInfo;
// 单链表
class SingleLink
{
public:
SingleLink();
~SingleLink();
// 创建节点
STGoodsInfo* CreateNode(STGoodsInfo& stGoodsInfo);
//(增)后插节点
bool InsertNodeBack(STGoodsInfo* pHead ,STGoodsInfo& stGoodsInfo);
//(增)前插节点
bool InserNodePre(STGoodsInfo*pHead,STGoodsInfo& stGoodsInfo);
//(增)插入到指定地点
bool InsertNodeAppointPos(STGoodsInfo* pHead,STGoodsInfo& stGoodsInfo);
// 删除指定位置的节点
STGoodsInfo* Remove(STGoodsInfo*pHead,int iPos);
// 修改节点
bool ChangeNode(STGoodsInfo*pHead,int iPos, STGoodsInfo& stGoodsInfo);
// 查找节点
int SelectNode(STGoodsInfo*pHead, STGoodsInfo& stGoodsInfo);
// 遍历链表
void PrintLink(STGoodsInfo*pHead);
// 清空链表
void ClearLink(STGoodsInfo*pHead);
// 合并链表
void AppendLink(STGoodsInfo*pHead, STGoodsInfo*pHead2);
// 链表长度
int Size(STGoodsInfo*pHead);
// 测试链表
void TestLink();
// 测试链表2
void TestLinkFunc();
private:
};
SingleLink.cpp
#include "SingleLink.h"
SingleLink::SingleLink()
{
}
SingleLink::~SingleLink()
{
}
// 创建节点
STGoodsInfo* SingleLink::CreateNode(STGoodsInfo& stGoodsInfo)
{
STGoodsInfo*newNode = (STGoodsInfo*)malloc(sizeof(STGoodsInfo));
strcpy(newNode->chName, stGoodsInfo.chName);
newNode->iPrice = stGoodsInfo.iPrice;
newNode->pNext = stGoodsInfo.pNext;
return newNode;
}
// 后插节点
bool SingleLink::InsertNodeBack(STGoodsInfo* pHead, STGoodsInfo& stGoodsInfo)
{
if(NULL == pHead)
{
cout << " 头结点为空"<< endl;
return false;
}
while(NULL != pHead->pNext)
{
pHead = pHead->pNext;
}
STGoodsInfo* nextNode = CreateNode(stGoodsInfo);
pHead->pNext = nextNode;
return true;
}
// 前插节点
bool SingleLink::InserNodePre(STGoodsInfo*pHead, STGoodsInfo& stGoodsInfo)
{
if(NULL == pHead)
{
cout << " 头结点为空" << endl;
return false;
}
STGoodsInfo* nextNode = CreateNode(stGoodsInfo);
nextNode->pNext = pHead->pNext;
pHead->pNext = nextNode;
return true;
}
// 插入到指定地点
bool SingleLink::InsertNodeAppointPos(STGoodsInfo* pHead, STGoodsInfo& stGoodsInfo)
{
return true;
}
// 移除节点
STGoodsInfo* SingleLink::Remove(STGoodsInfo*pHead, int iPos)
{
if(NULL == pHead)
{
return NULL;
}
if(iPos <=0)
{
return NULL;
}
STGoodsInfo* pTemp = pHead->pNext;
// 遍历到待删除节点的前一个节点
for(int i = 1;i<iPos;i++)
{
pHead = pHead->pNext;
pTemp = pHead;
}
// 待删除节点
STGoodsInfo* pDel = pTemp->pNext;
pTemp->pNext = pDel->pNext;
free(pDel);
pDel = NULL;
return pHead;
}
// 修改节点
bool SingleLink::ChangeNode(STGoodsInfo*pHead, int iPos, STGoodsInfo& stGoodsInfo)
{
if(NULL == pHead)
{
return false;
}
pHead = pHead->pNext; // 第一个节点
for(int i = 1;i< iPos;i++)
{
pHead = pHead->pNext;
}
strcpy(pHead->chName, stGoodsInfo.chName);
pHead->iPrice = stGoodsInfo.iPrice;
return true;
}
// 查找节点
int SingleLink::SelectNode(STGoodsInfo*pHead, STGoodsInfo& stGoodsInfo)
{
return 0;
}
// 打印链表
void SingleLink::PrintLink(STGoodsInfo*pHead)
{
if(NULL == pHead)
{
cout << "链表为空" << endl;
return;
}
pHead = pHead->pNext;
while(pHead)
{
char chName[20];
strcpy(chName, pHead->chName);
int iPrice = pHead->iPrice;
cout << "商品名称"<< chName << endl;
cout << "商品价格" << iPrice << endl;
cout << "**************"<< endl;
pHead = pHead->pNext;
}
}
// 清空链表
void SingleLink::ClearLink(STGoodsInfo*pHead)
{
}
// 合并链表
void SingleLink::AppendLink(STGoodsInfo*pHead, STGoodsInfo*pHead2)
{
if( (NULL== pHead)
|| (NULL == pHead2) )
{
return;
}
while(pHead->pNext)
{
pHead = pHead->pNext;
}
STGoodsInfo* pDelHead = pHead2;
pHead->pNext = pHead2->pNext;
free(pDelHead);
pDelHead = NULL;
}
int SingleLink::Size(STGoodsInfo*pHead)
{
int iCount = 0;
pHead = pHead->pNext;
while(pHead)
{
if(NULL != pHead)
{
iCount++;
}
pHead = pHead->pNext;
}
return iCount;
}
/*
对水果进行增删改查,
水果和手机链表合并
最后销毁
*/
void SingleLink::TestLink()
{
STGoodsInfo *pHead = NULL;
pHead = (STGoodsInfo*)malloc(sizeof(STGoodsInfo));
pHead->pNext = NULL;
// 新增苹果
STGoodsInfo stApple;
strcpy(stApple.chName,"apple");
stApple.iPrice = 4;
stApple.pNext = NULL;
InsertNodeBack(pHead, stApple);
// 新增橘子
STGoodsInfo stOrange;
strcpy(stOrange.chName, "Orange");
stOrange.iPrice = 5;
stOrange.pNext = NULL;
InsertNodeBack(pHead, stOrange);
// 新增甜瓜
STGoodsInfo stMelon;
strcpy(stMelon.chName, "Melon");
stMelon.iPrice = 6;
stMelon.pNext = NULL;
InsertNodeBack(pHead, stMelon);
// 新增可可
STGoodsInfo stCoco;
strcpy(stCoco.chName, "Coco");
stCoco.iPrice = 7;
stCoco.pNext = NULL;
InsertNodeBack(pHead, stCoco);
//PrintLink(pHead);
// 第二条链表
STGoodsInfo *pPhoneLink;
pPhoneLink = (STGoodsInfo *)malloc(sizeof(STGoodsInfo));
pPhoneLink->pNext = NULL;
STGoodsInfo stiPhone;
strcpy(stiPhone.chName, "iPhoneX");
stiPhone.iPrice = 10;
stiPhone.pNext = NULL;
InsertNodeBack(pPhoneLink, stiPhone);
STGoodsInfo stHUAWEI;
strcpy(stHUAWEI.chName, "HUAWEI P30 Pro");
stHUAWEI.iPrice = 20;
stHUAWEI.pNext = NULL;
InsertNodeBack(pPhoneLink, stHUAWEI);
AppendLink(pHead,pPhoneLink);
PrintLink(pHead);
//pHead->
}
void SingleLink::TestLinkFunc()
{
STGoodsInfo *pHead = NULL;
pHead = (STGoodsInfo*)malloc(sizeof(STGoodsInfo));
pHead->pNext = NULL;
// 新增苹果
STGoodsInfo stApple;
strcpy(stApple.chName, "apple");
stApple.iPrice = 4;
stApple.pNext = NULL;
InserNodePre(pHead, stApple);
// 新增橘子
STGoodsInfo stOrange;
strcpy(stOrange.chName, "Orange");
stOrange.iPrice = 5;
stOrange.pNext = NULL;
InserNodePre(pHead, stOrange);
// 新增甜瓜
STGoodsInfo stMelon;
strcpy(stMelon.chName, "Melon");
stMelon.iPrice = 6;
stMelon.pNext = NULL;
InserNodePre(pHead, stMelon);
// 新增可可
STGoodsInfo stCoco;
strcpy(stCoco.chName, "Coco");
stCoco.iPrice = 7;
stCoco.pNext = NULL;
InserNodePre(pHead, stCoco);
PrintLink(pHead);
//InserNodePre
}
main.cpp
#include<iostream>
using namespace std;
#include "SingleLink.h"
int main()
{
SingleLink mSingleLink;
mSingleLink.TestLink();
cin.get();
return 0;
}