您的位置:首页 > 理论基础 > 数据结构算法

数据结构--单向链表(c++)

2015-09-09 20:39 423 查看
1、单向链表:必要属性 头指针指针, 元素的实际长度, 结构体:数据、指向下一节点的指针

2、操作方法:

//判断链表是否为空
//清空链表
//返回链表的长度
//获取索引处元素内容
//获取指定内容的第一个元素的位置
//插入一个节点
//删除一个节点


#include  <stdlib.h>
#include <windows.h>
#include <iostream>

template<class Type>
class CLinkList
{

public:
typedef  struct _NODE
{
Type nData;
_NODE * pNext;
}NODE, *PNODE;

public:
CLinkList():m_nHead(nullptr),m_nLen(0)
{

}
~CLinkList()
{

}

public:

//判断链表是否为空
bool LListIsEmpty()
{

return (m_nLen == 0|| m_nHead==nullptr ) ? true : false;
}

//清空链表
void LListCls()
{
//如果头指针不为空  或者 长度不为0 则进行清空链表
if (m_nHead != nullptr || m_nLen != 0)
{
//记录当前指针变量
PNODE temp = m_nHead;
while(temp->pNext)
{
//将头指针后移
m_nHead = temp->pNext;
delete temp;
temp = nullptr;
//将新的头指针赋给临时变量
temp = m_nHead;
}

//删除最后一个节点  并将长度设置为0
delete m_nHead;
m_nHead = nullptr;
m_nLen = 0;
}
}

//返回链表的长度
int LListLen()
{
return m_nLen;
}

//获取索引处元素内容
bool LListGetEle(_In_ int idx, _Out_ Type &type)
{
//判断参数
if (idx<0 || idx>m_nLen)
{
return false;
}

//判断是否为空
if (m_nHead == nullptr || m_nLen == 0)
{
return false;
}

//遍历到要寻找的位置  从0开始 到idx前一个节点 就可以获取到idx中的内容
PNODE temp = m_nHead;
for (int i=0; i<idx; i++)
{
temp = temp->pNext;
}

//将内容传出
memcpy_s(&type, sizeof(Type), &(temp->nData), sizeof(Type));
return true;
}

//获取指定内容的第一个元素的位置
int LListGetIdx(_In_ Type data)
{
//判断是否为空
if (LListIsEmpty())
{
return -1;
}

//遍历 获取所在的位置
PNODE temp = m_nHead;
for (int i=0; i<m_nLen; i++)
{
//比较内容
if (!memcmp(&data,  &temp->nData, sizeof(Type)))
{
return i;
}
temp = temp->pNext;
}
return -1;
}

//插入一个节点
bool LListInsert(_In_ int idx, _In_ Type data)
{
// 判断参数
if (idx < 0 || idx > m_nLen)
{
return false;
}

//判断头结点是否为空
if (!m_nHead)
{
m_nHead = new NODE;
m_nHead->nData = data;
m_nHead->pNext = nullptr;
m_nLen++;
return true;
}

//找到要插入的节点
PNODE temp = new NODE;
temp->nData = data;
temp->pNext = nullptr;

//判断是否在头节点处插入
if (idx == 0)
{
//将该节点的pNext 指向 当前的头指针
temp->pNext = m_nHead;

//将头指针指向头节点
m_nHead = temp;

//长度自增
m_nLen++;
return true;
}

//插入的是非头结点
//记录头指针
PNODE pre = m_nHead;
//将记录指针移动到添加位置的前面
for(int i=0; i<idx; i++)
{
pre = pre->pNext;
}

//将当前节点的pNext赋值给temp的pNext
temp->pNext = pre->pNext;

//将temp的地址赋给 当前节点的pNext
pre->pNext = temp;

//长度自增
m_nLen++;

return true;
}

//删除一个节点
bool LListDel(_In_ int idx, _Out_ Type& data)
{
//判断参数
if (idx<0 || idx>=m_nLen)
{
return false;
}

//判断是否为空
if (LListIsEmpty())
{
return false;
}

//找到要删除的位置
//如果是头节点
if (idx == 0)
{
//将要删除的数据 赋值给传出数据
data = m_nHead->nData;

//创建一个临时节点
PNODE temp = new NODE;
temp = m_nHead;
temp = temp->pNext;
m_nHead = temp;

delete temp;
temp = nullptr;
//长度自减
m_nLen--;
return true;
}

//正常情况
//记录当前指针
PNODE temp = m_nHead;

//遍历到 要删除节点的前一个节点
for (int i = 0; i < idx-1; i++)
{
//当前节点的指针 移动到下一个节点
temp = temp->pNext;
}

//删除

//记录当前节点的pNext 此时temp为要删除的节点前一个节点
PNODE pre = nullptr;
pre = temp->pNext;  //要删除节点的地址
//将数据传出
data = pre->nData;
temp->pNext = pre->pNext;
delete pre;
pre = nullptr;

m_nLen--;
return true;
}

//打印输出
void pri()
{
PNODE temp = m_nHead;
for (int i=0 ; i<m_nLen; i++)
{
std::cout << temp->nData <<std::endl;
temp = temp->pNext;
}
std::cout<<std::endl;
}
private:
PNODE m_nHead;		//头指针
int m_nLen;			//元素个数
};

int main()
{

CLinkList<int>  cll;
cll.LListInsert(0, 11);
cll.LListInsert(0, 22);
cll.LListInsert(0, 33);

cll.pri();

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: