此数据结构的ADT就不说了,用链式实现线性表。实现的版本中包含一个head节点,用于指向线性表。
链表的长度包括a1~an。
下面是用C++模板类实现的一个链表方式存储的线性表linklist
/*
* =====================================================================================
*
* Filename: 3linklist.h
*
* Description: template implement of link-list
*
* Version: 1.0
* Created: 2012年03月09日 00时44分53秒
* Revision: none
* Compiler: gcc
*
* Author: Lavey Luo (lavey), luoyi.smt@gmail.com
* Organization:
*
* =====================================================================================
*/
#ifndef __LINKLINS_H__
#define __LINKLINS_H__
#include <cstdlib>
#include <ctime>
namespace st
{
#ifndef _STATUS_CONST_
#define _STATUS_CONST_
enum Status
{
OK = 0,
ERROR = -1
};
#endif
template<typename T>class linklist;
template<class T>
class linknode
{
friend class linklist<T>;
private:
T data;
linknode* next;
};
template<class T>
class linklist
{
public:
explicit linklist(): _head(NULL){
};
~linklist(){
};
public:
/* 初始化线性表 */
Status Init();
/* 初始条件:线性表已存在。操作结果:若L为空表,则返回OK,否则返回ERROR*/
Status Empty();
/* 初始条件:线性表已存在。操作结果:将L重置为空表 */
Status Clear();
/* 初始条件:线性表已存在。操作结果:返回L中数据元素个数 */
int Length();
/* 初始条件:线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 */
Status GetElem(int i, T& e);
/* 初始条件:线性表L已存在 */
/* 操作结果:返回第1个与e满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为ERROR */
int Locate(const T& e);
/* 初始条件:线性表已存在,1≤i≤ListLength(L), */
/* 操作结果:第i个位置之前插入新的数据元素e,长度加1 */
Status Insert(int i,const T& e);
/* 初始条件:线性表L已存在 */
/* 操作结果:在顺序线性表的尾端添加一个元素,长度加1 */
Status Pushback(const T& e);
/* 初始条件:线性表已存在,1≤i≤ListLength(L) */
/* 操作结果:删除的第i个数据元素,并用e返回其值,L的长度减1 */
Status Delete(int i, T& e);
/* 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
Status CreateListHead(int n);
/* 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
Status CreateListTail(int n);
private:
linknode<T>* _head;
};
template<class T>
Status linklist<T>::Init()
{ /* 产生头结点,并使L指向此头结点 */
_head = new linknode<T>;// malloc(sizeof(linknode));
if(!_head) /* 存储分配失败 */
return ERROR;
_head->next=NULL; /* 指针域为空 */
return OK;
}
template<class T>
Status linklist<T>::Empty()
{
if (_head->next)
return ERROR;
else
return OK;
}
template<class T>
Status linklist<T>::Clear()
{
if (!_head->next)
return OK;
linknode<T>* p = _head->next;
while(_head->next)
{
_head->next = p->next;
delete p;
p = _head->next;
}
return OK;
}
template<class T>
int linklist<T>::Length()
{
if (!_head->next)
return 0;
int len = 0;
linknode<T>* p = _head->next;
while (p)
{
len++;
p = p->next;
}
return len;
}
template<class T>
Status linklist<T>::GetElem(int i, T& e)
{
if (!_head->next || i < 1)
return ERROR;
linknode<T>* p = _head->next;
do {
i--;
p = p->next;
} while ( i > 0 && p ); /* ----- end do-while ----- */
e = p->data;
return OK;
}
template<class T>
int linklist<T>::Locate(const T& e)
{
if (!_head->next)
return ERROR;
linknode<T>* p = _head->next;
int i = 0;
do {
i++;
if (p->data == e)
return i;
p = p->next;
} while ( p ); /* ----- end do-while ----- */
return ERROR;
}
template<class T>
Status linklist<T>::Insert(int i, const T& e)
{
if (!_head || i < 1)
return ERROR;
linknode<T>* p = _head;
int j = 1;
while ( p && j < i ) {
p = p->next;
j++;
}
if (!p || j > i )
return ERROR;
linknode<T>* q = new linknode<T>;
q->data = e;
q->next = p->next;
p->next = q;
return OK;
}
template<class T>
Status linklist<T>::Pushback(const T& e)
{
if (!_head->next)
return ERROR;
linknode<T> *q = new linknode<T>;
if (!q) return ERROR;
q->data = e;
q->next = NULL;
linknode<T>* p = _head;
while ( p->next )
{
p = p->next;
}
p->next = q;
return OK;
}
template<class T>
Status linklist<T>::Delete(int i, T& e)
{
if (!_head->next || i < 1)
return ERROR;
linknode<T>* p = _head->next;
int j = 1;
do {
p = p->next;
j++;
} while ( p->next && j < i ); /* ----- end do-while ----- */
if ( !p->next ) return ERROR;
linknode<T>* q = p->next;
e = q->data;
p->next = q->next;
delete q;
return OK;
}
template<class T>
Status linklist<T>::CreateListHead(int n)
{
if (_head || n < 1) return ERROR;
linknode<T>* p = NULL;
int i = 0;
srand(time(0)); /* 初始化随机数种子 */
_head = new linknode<T>;
if (!_head) return ERROR;
_head->next = NULL; /* 先建立一个带头结点的单链表 */
linknode<T>* q = _head; /* 表头 */
for ( ; i < n ; i++ )
{
p = new linknode<T>;
if (!p) return ERROR;
p->data = rand() % 100 + i;
p->next = q->next;
q->next = p; /* 插入到表头 */
}
return OK;
}
template<class T>
Status linklist<T>::CreateListTail(int n)
{
if (_head || n < 1) return ERROR;
linknode<T>* p = NULL;
int i = 0;
srand(time(0)); /* 初始化随机数种子 */
_head = new linknode<T>;
if (!_head) return ERROR;
_head->next = NULL; /* 先建立一个带头结点的单链表 */
linknode<T>* q = _head; /* 尾表 */
for ( ; i < n ; i++ )
{
p = new linknode<T>;
if (!p) return ERROR;
p->data = rand() % 100 + i;
q->next = p;
q = p;
}
return OK;
}
}
#endif //__LINKLINS_H__
还有对linklist的测试用例:
/*
* =====================================================================================
*
* Filename: test_linklist.cpp
*
* Description: test case of the 3linklinst.h
*
* Version: 1.0
* Created: 2012年03月11日 21时58分59秒
* Revision: none
* Compiler: gcc
*
* Author: Lavey Luo (lavey), luoyi.smt@gmail.com
* Organization:
*
* =====================================================================================
*/
#include "3linklist.h"
#include <stdio.h>
int test_linklinst (int argc, char** argv)
{
st::linklist<int> list1;
list1.Init();
if (list1.Empty() == st::OK)
puts("the list1 is empty");
printf(" list1 len %d\n", list1.Length());
puts("insert 1..5 to the list1");
for (int i = 1; i <= 5; i++)
list1.Insert(i, i);
printf(" list1 len %d\n", list1.Length());
puts("to push 200 to the end of list1");
list1.Pushback(200);
printf(" list1 len %d\n", list1.Length());
printf("locate of 200 in list1 is:%d \n", list1.Locate(200));
printf("locate of 3 in list1 is:%d \n", list1.Locate(3));
puts("clear the list1");
list1.Clear();
printf(" list1 len %d\n", list1.Length());
st::linklist<float> flist1;
flist1.CreateListHead(10);
printf(" flist1 len %d\n", flist1.Length());
st::linklist<float> flist2;
flist2.CreateListTail(10);
printf(" flist1 len %d\n", flist2.Length());
return 0;
}