普通链表

近期打算把一些常用的数据结构自己实现一遍。

采用C++风格。为简单,不作泛型处理,不考虑new失败情况。仅选取少数个人认为最常见的方法实现。

所贴代码均为本人所写,不保证无误。


个人对链表的理解:

相对最简单的数组,链表强在增删,弱在查找。


实现链表最关键的是定义节点结构(数据+下节点指针),其次是链表记录方式,本来只记一个头指针就可以了,但为使用方便,一般多记录一些信息,如尾指针、长度,等。

以下是代码:

/*
2014.4.16
普通链表的简单实现
*/
#include "stdafx.h"
#include <iostream>
using namespace std;

class node
{
public:
    int data;
    node *next;
};

class CMyList
{
public:
    node *head;
    node *tail;

    node *Find(int data);   //查找某元素值,并返回节点指针

    void Add(int data);     //在尾部插入元素值为data的节点

    //在值为old_data的节点后插入值为new_data的节点,若找不到old_data,则在尾部插入
    void Insert(int old_data, int new_data);

    void Show();    //在控制台显示所有元素值

    CMyList(void);
    ~CMyList(void);
};

CMyList::CMyList()
{
    head = new node;
    tail = head;
}

CMyList::~CMyList()
{
    node *p = head;
    while (p != NULL)
    {
        node *tmp = p;
        p = p->next;
        delete tmp;
        tmp = NULL;
    }
}

node *CMyList::Find(int data)
{
    if (tail == NULL)
    {
        cout<<"the list is empty"<<endl;
        return NULL;
    }
    else
    {
        node *tmp = head;
        while (tmp->data != data)
        {
            tmp = tmp->next;
            if (tmp == NULL)
            {
                cout<<"data do not exist"<<endl;
                return NULL;
            }
        }

        //found
        return tmp;
    }
}

void CMyList::Add(int data)
{
    node *new_node = new node;
    new_node->data = data;
    new_node->next = NULL;

    tail->next = new_node;

    tail = new_node;
}

void CMyList::Insert(int old_data, int new_data)
{
    node *tmp = NULL;
    tmp = Find(old_data);

    if ((tmp == NULL) || (tmp == tail))
    {
        Add(new_data);
    }
    else 
    {
        node *new_node = new node;
        
        new_node->data = new_data;
        new_node->next = tmp->next;

        tmp->next = new_node;
    }
}

void CMyList::Show()
{
    //最好先检测是否为空表,并给出提示
    if (head == tail)
    {
        cout<<"the list is empty"<<endl;
        return;
    }

    else
    {
        node *tmp = head->next; //注意头节点是没有数据的,必须从头节点的下一个节点开始显示
        while (tmp != NULL)
        {
            cout<<tmp->data<<" ";
            tmp = tmp->next;
        }
        cout<<endl;
    }
}

void main()
{
    CMyList list;       list.Show();
    list.Add(1);        list.Show();
    list.Add(3);        list.Show();
    list.Find(2);
    list.Insert(4, 4);  list.Show();
    list.Insert(1, 2);  list.Show();
}

/*
执行结果:
the list is empty
1
1 3
data do not exist
data do not exist
1 3 4
1 2 3 4

注意点:
1,链表的头节点是不存数据的,遍历一定要从头节点的下一个节点开始
2,插入的每个节点都是单独开辟的内存空间,所以销毁链表时,也一定要每个都删掉
3,tail节点的记录是为了便于在尾部插入,但注意Insert若刚好是在尾部时,也要更新tail记录,最好的办法如程序所示,if(tmp == tail),也用Add()
*/







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值