博文源于王卓老师的数据结构实现版本并做了测试,有需要的读者可以收藏。
1、线性表的链式存储结构
typedef struct LNode{
ElementType data;
struct LNode*next;
}LNode,*LinkList;
2、初始化链表
初始化链表就是分配内存,设置为Next为null
Status InitList(LinkList &L){
L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
L->next= NULL; //头结点的指针值为空
return OK;
}
3、头插法创建链表
头插法创建链表主要是针对L的next指向新创建结点。
void CreateList_T(LinkList &L,int n){
L = new LNode;
L->next = NULL;
LinkList r = L;
for(int i =0;i<n;i++){
LinkList p = new LNode; // 生成新结点
cin >> p->data; //输入元素赋给新结点*p 的数据域
p->next = NULL; //将新结点*p 插入尾结点*r 之后
r->next = p;
r = p; //r指向新的尾结点
}
}
4、尾插法创建链表
尾部插入主要要有一个尾指针。
void CreateList_H(LinkList &L,int n){
//逆位序输入n个元素的值,建立带表头结点的单链表L
L = new LNode;
L->next = NULL;
for(int i=0;i<n;i++){
LinkList p = new LNode;
cin >> p->data;
p->next = L->next;
L->next = p;
}
}
5、链表插入
- 1、查找结点a_(i-1) 并由指针p指向该结点
- 2、生成1个新结点s
- 3、将新结点*s 数据域置为e
- 4、将新结点*s 的指针域指向结点a_i
- 5、将结点*p 的指针域指向新结点s
Status ListInsert(LinkList &L,int i,ElementType e){
LinkList p = L;
int j = 0;
while(p && j<i-1){
p = p->next;
j++;
}
if(!p || j>i-1) return ERROR;//查找第i-1个新结点,p指向该节点
LNode* s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
6、 链表删除第一个值
- 1、查找结点a_(i-1) 并由指针p指向该节点
- 2、临时保存待删除节点a_i 的地址在q中,以备释放
- 3、将结点*p 的指针域指向a_i的直接后继结点
- 4、释放结点a_i的空间
Status ListDelete(LinkList &L,int i){
//带头结点的单链表L中,删除第i个元素
LinkList p = L;
int j =0;
while((p->next) && j<i-1){
p = p->next;
j++;
}
if(!(p->next) || (j>i-1)) return ERROR;
LNode *q = p->next;
p->next = q->next;
delete q;
return OK;
}
7、链表打印(补充)
打印一下整个链表,一跳一跳
void Print(LinkList L){
LinkList p = L->next;
while(p){
cout << p->data << " ";
p=p->next;
}
cout << endl;
}
8、获取第i个链表的值
这也是与链表打印有着相同的原理。
Status GetElem(LinkList L,int i,ElementType &e){
LinkList p = L->next; //指向第一号结点
int j =1; //第一位
while(p && j<i){
p=p->next;
j++;
}
if(!p || j>i) return ERROR; //i值不合法,i>n 或i<=0
e = p->data;//取第i个结点的数据域
return OK;
}
9、查找元素e是否存在
跟链表打印相似
LNode *LocateElem(LinkList L,ElementType e){
LinkList p = L->next;
while(p && p->data!=e){
//如果data不是那就往后跳,跳到p为空
p=p->next;
}
return p; //查找成功返回p,否则返回NULL
}
10、链表是否为空(补充,自己测试用)
判断L就行了
Status IsEmpty(LinkList L){
if(L->next){
return FALSE;
}else return TRUE;
}
测试效果
完整代码
#include<iostream>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 10
using namespace std;
typedef int Status;
typedef int ElementType;
//线性表的顺序存储
typedef struct LNode{
ElementType data;
struct LNode*next;
}LNode,*LinkList;
Status InitList(LinkList &L){
L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
L->next= NULL; //头结点的指针值为空
return OK;
}
Status IsEmpty(LinkList L){
if(L->next){
return FALSE;
}else return TRUE;
}
Status GetElem(LinkList L,int i,ElementType &e){
LinkList p = L->next; //指向第一号结点
int j =1; //第一位
while(p && j<i){
p=p->next;
j++;
}
if(!p || j>i) return ERROR; //i值不合法,i>n 或i<=0
e = p->data;//取第i个结点的数据域
return OK;
}
LNode *LocateElem(LinkList L,ElementType e){
LinkList p = L->next;
while(p && p->data!=e){
//如果data不是那就往后跳,跳到p为空
p=p->next;
}
return p; //查找成功返回p,否则返回NULL
}
/*单链表的插入
* 1、查找结点a_(i-1) 并由指针p指向该结点
* 2、生成1个新结点s
* 3、将新结点*s 数据域置为e
* 4、将新结点*s 的指针域指向结点a_i
* 5、将结点*p 的指针域指向新结点s
* */
Status ListInsert(LinkList &L,int i,ElementType e){
LinkList p = L;
int j = 0;
while(p && j<i-1){
p = p->next;
j++;
}
if(!p || j>i-1) return ERROR;//查找第i-1个新结点,p指向该节点
LNode* s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
/*单链表的删除
* 1、查找结点a_(i-1) 并由指针p指向该节点
* 2、临时保存待删除节点a_i 的地址在q中,以备释放
* 3、将结点*p 的指针域指向a_i的直接后继结点
* 4、释放结点a_i的空间
* */
Status ListDelete(LinkList &L,int i){
//带头结点的单链表L中,删除第i个元素
LinkList p = L;
int j =0;
while((p->next) && j<i-1){
p = p->next;
j++;
}
if(!(p->next) || (j>i-1)) return ERROR;
LNode *q = p->next;
p->next = q->next;
delete q;
return OK;
}
void CreateList_H(LinkList &L,int n){
//逆位序输入n个元素的值,建立带表头结点的单链表L
L = new LNode;
L->next = NULL;
for(int i=0;i<n;i++){
LinkList p = new LNode;
cin >> p->data;
p->next = L->next;
L->next = p;
}
}
void Print(LinkList L){
LinkList p = L->next;
while(p){
cout << p->data << " ";
p=p->next;
}
cout << endl;
}
void CreateList_T(LinkList &L,int n){
L = new LNode;
L->next = NULL;
LinkList r = L;
for(int i =0;i<n;i++){
LinkList p = new LNode; // 生成新结点
cin >> p->data; //输入元素赋给新结点*p 的数据域
p->next = NULL; //将新结点*p 插入尾结点*r 之后
r->next = p;
r = p; //r指向新的尾结点
}
}
int main(){
LinkList L;
InitList(L);
cout << "After init is L empty?:" << IsEmpty(L) << endl;
ListInsert(L,1,1);
ElementType e;
GetElem(L,1,e);
cout << "After insert,get elem is :"<< e << endl;
LinkList p = LocateElem(L,1);
cout << "search 1,is in?:" << p->data << endl;
ListDelete(L,1);
cout << "after delete is L empty?:" << IsEmpty(L) << endl;
CreateList_H(L,5);
cout << "head insert:" << endl;
Print(L);
CreateList_T(L,5);
cout << "tail insert:" << endl;
Print(L);
return 0;
}