近期打算把一些常用的数据结构自己实现一遍。
采用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()
*/