关于单链表的几种操作实现

注意:
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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值