单链表算是一种最为简单以及基础的数据结构之一,链式存取。关于它的介绍就省略了,直接上代码。
类的声明
template<class Tpye>
class LinkList{
protected:
typedef struct LinkNode{ //链表结点
Type data;
struct LinkNode* next;
};
public:
LinkList();
~LinkList();
static LinkNode *Buynode();
static void Freenode(LinkNode *p);
public:
int empty(); //判断链表是否为空
void push_back(const Type& value); //尾插
void pop_back; //尾删
void push_front(const Type& value); //头插
void pop_front(); //头删
void reverse(); //逆置单链表
void show_list(); //显示单链表元素
private:
LinkNode *head;
};
代码实现
#include<iostream>
#include<assert.h>
using namespace std;
template<class Type>
class LinkList{
protected:
typedef struct LinkNode{
Type data;
struct LinkNode* next;
};
public:
LinkList()
{
head = Buynode();
}
~LinkList()
{
if(empty())//如果链非空,则调用头删函数,一个一个释放
{
for(int i=0;i<head->data;++i)
{
pop_front();
}
}
Freenode(head);//最后释放头结点
}
static LinkNode *Buynode()
{
LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
assert(s != NULL);
memset(s,0,sizeof(LinkNode));
return s;
}
static void Freenode(LinkNode *p)
{
free(p);
}
public:
int empty()
{
return head->data==0?1:0;
}
void push_back(const Type& value)//尾插
{
LinkNode *s = Buynode();
s->data = value;
head->data++;
LinkNode *p = head->next;
if(p == NULL) //当前链表为空,只有头结点
{
head->next=s;
return;
}
while(p->next != NULL)
{
p=p->next;
}
p->next = s;
}
void pop_back()
{
if( empty())
{
cout<<"linklist empty,pop_back error !"<<endl;
return;
}
head->data--;
LinkNode *p = head->next;
if(p->next == NULL)//当前链表只有一个数据结点
{
Freenode(p);
head->next=NULL;
return;
}
while(p->next->next != NULL)
{
p = p->next;
}
LinkNode *s = p->next;
Freenode(s);
p->next=NULL;
}
void push_front(const Type& value)//头插
{
LinkNode *s = Buynode();
s->data = value;
LinkNode *p = head->next;
head->next = s;
s->next = p;
head->data++;
}
void pop_front()
{
if( empty())
{
cout<<"linklist empty,pop_front error !"<<endl;
return;
}
LinkNode *p = head->next;
head->next = p->next;
Freenode(p);
head->data--;
}
void reverse()//
{
LinkNode *p=head->next;
LinkNode *s = NULL;
//断开头结点,将后边的数据结点一个一个头插到头结点,即实现逆置
head->next = NULL;
while(p)
{
s=p;
p=p->next;
s->next=head->next;
head->next=s;
}
}
void show_list()
{
LinkNode *p=head->next;
cout<<"data: ";//
while(p)
{
cout<<p->data<<" ";
p = p->next;
}
cout<<endl;
cout<<"size: "<<head->data<<endl;
}
private:
LinkNode *head;
};
int main()
{
int an[] = {1,2,3,4,5,6};
int len = sizeof(an)/sizeof(an[0]);
LinkList<int> mylist;
for(int i=0;i<len;++i)
{
//mylist.push_front(an[i]);
mylist.push_back(an[i]);
}
mylist.show_list();
mylist.reverse();
mylist.show_list();
for(i=0;i<len+1;++i)
{
mylist.pop_front();
//mylist.pop_back();
mylist.show_list();
}
return 0;
}
运行结果:
data: 1 2 3 4 5 6
size: 6
data: 6 5 4 3 2 1
size: 6
data: 5 4 3 2 1
size: 5
data: 4 3 2 1
size: 4
data: 3 2 1
size: 3
data: 2 1
size: 2
data: 1
size: 1
data:
size: 0
linklist empty,pop_front error !
data:
size: 0
Press any key to continue
注意:
细心的读者可能看出来,我用头结点的数据域(data)存放链表的长度。
虽然我是用c++模板类实现单链表,可以实现通用类型(Type),但是存在一个问题:那就是如果Type的类型非int,那么头结点的数据域(head->data)打印结果将是乱码,并非链表的长度,这也很好理解,因为它不是整型。这种情况的话只能在私有变量中增加一个size成员,记录链表长度。
图示说明