单链表(测试)
更新
#include <stdlib.h>
//////////////////////////////////////////////////////////////////////////
//单链表
//////////////////////////////////////////////////////////////////////////
//链表节点
struct ListNode
{
void* pData; //要存储的数据
ListNode* pNext; //执向下一个节点
};
struct OnlyList
{
OnlyList():pHead(nullptr),nSize(0)
{
}
ListNode* pHead; //添加一个头指针,方便操作
unsigned int nSize; //链表节点有效个数,方便知道总共有多少个节点
};
//增加元素
////////////////////////////////////////////////////////////////////////////////////////////////////
//往链表中添加数据,默认从头插入,即头插法
//1.链表需要已经存在的
//2.数据需要已经存在的
bool AddOnlyListBeginEle(OnlyList* pList, void* pdata)
{
//List和data任意一个为空则什么也不做
if (pList==nullptr || pdata == nullptr)
{
return false;
}
//创建一个新的节点
ListNode* pNode = (ListNode*)malloc(sizeof(ListNode));
//复制数据指针变量
pNode->pData = pdata;
//把链表头指针赋给新节点的下一个节点的指针
pNode->pNext = pList->pHead;
//把新节点的指针赋给链表的头指针
pList->pHead = pNode;
//链表节点增加一个
pList->nSize++;
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//删除元素
////////////////////////////////////////////////////////////////////////////////////////////////////
//删除链表中的首元素
bool DelOnlyListBeginEle(OnlyList* pList)
{
if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
{
return false;
}
//临时储存链表的头指针
ListNode* pTmp = pList->pHead;
//把链表的头指针所指向的下一个节点指针复制链表的头指针
pList->pHead = pTmp->pNext;
//有效个数减一
pList->nSize--;
//释放空间
//pTmp->pNext = nullptr;
free(pTmp);
return true;
}
//删除链表中的尾元素
bool DelOnlyListEndEle(OnlyList* pList)
{
if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
{
return false;
}
ListNode* pTmpEndNode = pList->pHead;
ListNode* pTmpPreEndNode = pTmpEndNode;
//////////////////////////////////////////////////////////////////////////
//找到尾结点---第一种方法---------------------------------------
//////////////////////////////////////////////////////////////////////////
//判断是否为空,不为空则循环,直到找到尾节点结束
while (pTmpEndNode->pNext) //查找节点的下一个节点指针是否为NULL
{
pTmpPreEndNode = pTmpEndNode; //存储本次循环节点,直到找到尾结点,即时尾结点的前一个节点
pTmpEndNode = pTmpEndNode->pNext; //存储本次循环节点的下一个节点指针,直到找到尾结点
}
//把倒数第二个下一个指针域赋值为nullptr
pTmpPreEndNode->pNext = nullptr;
//有效个数减一
pList->nSize--;
//释放尾结点空间
free(pTmpEndNode);
//当只有一个有效元素时
if (pList->nSize == 0)
{
pList->pHead = nullptr;
}
//////////////////////////////////////////////////////////////////////////
return true;
}
//在链表中删除指定索引的一个元素
bool DelOnlyListEleByIndex(OnlyList* pList,unsigned int index) //index索引从1开始
{
if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
{
return false;
}
ListNode* pTmpEndNode = pList->pHead;
ListNode* pTmpPreEndNode = pTmpEndNode;
for (unsigned int i=0; i< (index-1); i++)
{
pTmpPreEndNode = pTmpEndNode;
pTmpEndNode = pTmpEndNode->pNext;
}
pTmpPreEndNode->pNext = pTmpEndNode->pNext;
pList->nSize--;
free(pTmpEndNode);
//当只有一个有效元素时
if (pList->nSize == 0)
{
pList->pHead = nullptr;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//修改元素
////////////////////////////////////////////////////////////////////////////////////////////////////
//在链表中修改指定索引的一个元素
bool UpdateOnlyListEleByIndex(OnlyList* pList,unsigned int index,void* data) //index索引从1开始
{
if (pList == nullptr ||pList->nSize == 0 /*|| pList->pHead == nullptr*/)
{
return false;
}
if (index > (pList->nSize) || index <= 0)
{
return false;
}
ListNode* pTmpEndNode = pList->pHead;
for (unsigned int i=0; i< (index-1); i++)
{
pTmpEndNode = pTmpEndNode->pNext;
}
//赋值数据
pTmpEndNode->pData = data;
return true;
}
int main()
{
OnlyList list;
int a = 2;
int b = 3;
int c = 4;
int d = 5;
AddOnlyListBeginEle(&list,&a);
AddOnlyListBeginEle(&list,&b);
AddOnlyListBeginEle(&list,&c);
AddOnlyListBeginEle(&list,&d);
bool ret = false;
int f = 100;
ret = UpdateOnlyListEleByIndex(&list,10,&f);
ret = UpdateOnlyListEleByIndex(&list,1,&f);
//ret = DelOnlyListBeginEle(&list);
//ret = DelOnlyListEndEle(&list);
//ret = DelOnlyListEndEle(&list);
//ret = DelOnlyListBeginEle(&list);
//ret = DelOnlyListEle(&list,1);
//ret = DelOnlyListBeginEle(&list);
//ret = DelOnlyListBeginEle(&list);
return 0;
}
C++封装
#ifndef _JXLIST_H_
#define _JXLIST_H_
#include <stdlib.h>
template<typename T>
class CJxList
{
protected:
typedef struct _Node
{
T pData; //数据
struct _Node* pNext; //前驱指针
struct _Node* pPre; //后驱指针
}Node;
public:
CJxList(void):m_nSize(0),m_pHead(nullptr),m_pTail(nullptr)
{
}
~CJxList()
{
}
//在头增加数据
bool AddBeginEle(T pdata)
{
//创建一个新的节点
Node* pNewNode = (Node*)malloc(sizeof(Node));
//复制数据指针变量
pNewNode->pData = pdata;
//把新节点元素的前驱指针为空
pNewNode->pPre = nullptr;
//把链表头指针赋给新节点的下一个节点的指针
pNewNode->pNext = m_pHead;
//把节点赋给头指针
if (m_nSize == 0)
{
m_pTail = pNewNode;
}
else
{
m_pHead->pPre = pNewNode;
}
//把新节点的指针赋给链表的头指针
m_pHead = pNewNode;
//链表节点增加一个
m_nSize++;
return true;
}
//删除首数据并返回删除的数值
T DelBeginEle()
{
if (m_nSize == 0 /*|| m_pHead == nullptr*/)
{
return false;
}
//临时储存链表的头指针
Node* pTmp = m_pHead;
//把链表的头指针所指向的下一个节点指针复制链表的头指针
m_pHead = pTmp->pNext;
if (m_nSize == 1)
{
m_pTail = nullptr;
}
else
{
m_pHead->pPre = nullptr;
}
//有效个数减一
m_nSize--;
//释放空间
//pTmp->pNext = nullptr; //可有可无
T ret = pTmp->pData;
free(pTmp);
return ret;
}
//删除链表中的尾元素
T DelEndEle()
{
if (m_nSize == 0 /*|| m_pHead == nullptr*/)
{
return false;
}
//临时储存链表的头指针
Node* pTmp = m_pTail;
m_pTail = pTmp->pPre;
//有效个数减一
m_nSize--;
//释放空间
//pTmp->pNext = nullptr;
T ret = pTmp->pData;
free(pTmp);
return ret;
}
//指定索引修改一个数据
bool UpdataEleByIndex(unsigned int index,T data) //index索引从1开始
{
if (index > (m_nSize) || m_nSize <= 0)
{
return false;
}
Node* pTmpEndNode = m_pHead;
for (unsigned int i=0; i< (index-1); i++)
{
pTmpEndNode = pTmpEndNode->pNext;
}
//赋值数据
pTmpEndNode->pData = data;
return true;
}
//指定索引查找数据
T FindEleByIndex(unsigned int index) //index索引从1开始
{
if (index > (m_nSize) || index <= 0)
{
return (T)0;
}
Node* pTmpEndNode = m_pHead;
for (unsigned int i=0; i< (index-1); i++)
{
pTmpEndNode = pTmpEndNode->pNext;
}
//赋值数据
return pTmpEndNode->pData;
}
/*将数据节点置为空表,释放原节点空间*/
void Clear()
{
Node* pTmpNext = m_pHead; //临时节点指针
Node* pDelNode = m_pHead; //删除节点指针
while (pTmpNext!=m_pTail)
{
//保存临时节点
pDelNode = pTmpNext;
//将临时节点的下一个节点指针保存
pTmpNext = pTmpNext->pNext;
//释放内存
free(pDelNode);
m_nSize--;
}
free(m_pTail);
m_nSize--;
m_pHead = nullptr;
m_pTail = nullptr;
//m_nSize = 0;
}
/*返回链表大小*/
int GetSize()
{
return m_nSize;
}
//判断是否为空
bool IsEmpty(){ return (m_nSize ? false : true); }
private:
unsigned int m_nSize; //元素个数
Node* m_pHead; //头指针
Node* m_pTail; //尾指针
};
#endif