注意:
1.只要涉及对链表指针进行操作,一定要注意出错/特殊情况的判断(包括在函数的入口处、通过调用函数获取结果时)否则极容易造成访问越界
2. 链表的删除ClearList是否可以像数组一样一次性删除一段连续空间?
不行,除非静态链表
#include <iostream>
using namespace std;
//定义一个链表结点
struct LNode
{
int data;
LNode *next;
};
//定义一个链表结构
struct LinkList
{
LNode *pHead;//表头指针
LNode *pCurrent;//当前结点指针
int nLength;//表中结点数目(不含头结点)
};
//初始化链表
bool InitList(LinkList *pThis)
{
//若动态创建链表头结点为空则链表不存在
if(!(pThis -> pHead = new LNode))
return false;
pThis -> pHead -> next = NULL;
pThis -> nLength = 0;
pThis -> pCurrent = pThis -> pHead -> next;
return true;
}
//得到指定位置结点的指针
LNode *GetNode(LinkList *pThis, int position)
{
LNode *pTmp = NULL;
int curPos = 0;
pTmp = pThis -> pHead;
while(pTmp)
{
if(curPos == position)
break;
pTmp = pTmp -> next;
curPos++;
}
if(curPos != position)
return 0;
return pTmp;
}
//插入结点
bool InsertNode(LinkList *pThis, int beforeWhich, int ndata)
{
if(beforeWhich < 1 || beforeWhich > ( pThis -> nLength )+ 1)
return false;
LNode *pTmp = GetNode(pThis, beforeWhich - 1);
if(!pTmp)
return false;
LNode *NewNode = new LNode;
NewNode -> data = ndata;
NewNode -> next = pTmp -> next;
pTmp -> next = NewNode;
pThis -> nLength++;
return true;
}
//返回当前链表中的结点数
int GetLength(LinkList *pThis)
{
return pThis -> nLength;
}
//得到指定位置结点的数据,结点从1索引到nLength
bool GetNodeData(LinkList *pThis, int position, int &ndata)//此处data用的是引用,
{ //所以data实参值会改变
LNode *pTmp = GetNode(pThis, position);
if(!pTmp)
return false;
ndata = pTmp -> data;
return true;
}
//将position指定的结点内的数据设置为newData
//第一个有效结点为1
bool SetNodeData(LinkList *pThis, int position, int ndata)
{
LNode *pTmp = GetNode(pThis, position);
if(!pTmp)
return false;
pTmp -> data = ndata;
return true;
}
//将第一个结点设置为当前结点
void Rewind(LinkList *pThis)
{
pThis -> pCurrent = pThis -> pHead -> next;
}
//取当前结点数据,并移动到下一个结点
bool GetNextNodeData(LinkList *pThis, int *pData)
{
if(pThis -> pCurrent == NULL)
return false;
*pData = pThis -> pCurrent -> data;
pThis -> pCurrent = pThis -> pCurrent -> next;
return true;
}
//删除一个指定结点,结点位置由position指定
//position的值从1到nLength
//若链表为空或者指定的结点不存在则返回false
bool DeleteNode(LinkList *pThis, int position)
{
if(position < 1 || position > pThis -> nLength)
return false;
LNode *pTmp = GetNode(pThis, position - 1);
LNode *pDel = NULL;
if(!pTmp)
return false;
pDel = pTmp -> next;
pTmp -> next = pDel -> next;
delete pDel;
pThis -> nLength--;//删除结点后记得长度减一
return true;
}
//定位与指定数据相等的数据结点,如果在当前链表中已经存在该数据则返回该数据结点的位置
//若不存在这样的点则返回0
int LocateElem(LinkList *pThis, int elem)
{
LNode *pTmp = pThis -> pHead -> next;
int currentpos = 1;
while((pTmp != NULL) && (pTmp -> data != elem))
{
pTmp = pTmp -> next;
currentpos++;
}
if(pTmp == NULL)
return 0;
return currentpos;
}
//将链表清空,释放所有结点(不包括头结点)
bool ClearList(LinkList *pThis)
{
if(pThis -> pHead == NULL)
return false;
LNode *pTmp = NULL;
while(pThis -> pHead -> next != NULL)
{
pTmp = pThis -> pHead -> next;
pThis -> pHead -> next = pTmp -> next;
delete pTmp;
}
pThis -> nLength = 0;
return true;
}
//销毁链表
bool DestroyList(LinkList *pThis)
{
if(!ClearList(pThis))
return false;
delete pThis -> pHead;
return true;
}
//判读链表是否为空,若真返回true,假返回false
bool IsEmpty(LinkList *pThis)
{
if(pThis -> pHead -> next == NULL)
return true;
return false;
}
int main()
{
LinkList MyList;
InitList(&MyList);
InsertNode(&MyList, 1, 10);
InsertNode(&MyList, 2, 20);
InsertNode(&MyList, 3, 30);
InsertNode(&MyList, 4, 40);
int Len = GetLength(&MyList);
cout << Len << endl;
int dataTmp = 0;
for(int i = 1; i <= Len; ++i)
{
GetNodeData(&MyList, i, dataTmp);
cout << dataTmp << endl;
}
if(SetNodeData(&MyList, 3, 50))
{
cout << "Done" << endl;
}else
{
cout << "Falied" << endl;
}
Rewind(&MyList);
while(GetNextNodeData(&MyList, &dataTmp))
cout << dataTmp << endl;
if(DeleteNode(&MyList, 4))
{
cout << "Done" << endl;
}else
{
cout << "Failed" << endl;
}
int Len2 = GetLength(&MyList);
cout << Len2 << endl;
for(int i = 1; i <= Len2; ++i)
{
GetNodeData(&MyList, i, dataTmp);
cout << dataTmp << endl;
}
cout << LocateElem(&MyList, 40) << endl;
DeleteNode(&MyList, LocateElem(&MyList, 50));
DeleteNode(&MyList, LocateElem(&MyList, 20));
Rewind(&MyList);
while(GetNextNodeData(&MyList, &dataTmp))
cout << dataTmp << endl;
ClearList(&MyList);
IsEmpty(&MyList);
DestroyList(&MyList);
return 0;
}