线性链表

在链式存储结构中,存储数据结构的存储空间可以不连续,各数据结点的存储顺序与数据元素之间的逻辑关系可以不一致,而数据元素之间的逻辑关系是由指针域来确定的。链式存储方式即可以用于表示线性结构,也可用于表示非线性结构。
一般来说,在线性表的链式存储结构中,各数据结点的存储符号是不连续的,并且各结点在存储空间中的位置关系与逻辑关系也不一致。对于线性链表,可以从头指针开始,沿各结点的指针扫描到链表中的所有结点。

1.线性链表的实现

在实现之前先把需要使用到的库和头文件进行包含
所需的头文件sqlist.hlink_list.h已经在上方提供

#include <stdio.h> 
#include <stdlib.h>   
#include "sq_list.h" 
#include "link_list.h"
1)构造一个空的链表L
void InitList_L(struct LNode * &L){
	//构造一个空的链表L
	L = (struct LNode *)malloc(sizeof(LNode));
	L->next = NULL;
}//InitList_L
2)//销毁表L
void DestoryList_L(struct LNode * &L){
	//销毁表L
	free(L);
	L=NULL;
}//DestoryList_L
3)将表L重置为空表
void ClearList_L(struct LNode * &L){
	//将表L重置为空表
	L->next = NULL; 
}//ClearList_L
4)判断是否为空表
bool ListEmpty_L(struct LNode *&L){
	//判断是否为空表,是返回true,否则返回false;
	if(NULL == L->next)
		return true;
	else
		return false;
}//ListEmpty_L
5)获取链表L中数据元素的个数
int ListLength_L(struct LNode * &L){
	//返回L中数据元素的个数
	int len = 0;//计数
	struct LNode *p = L->next;
	while(NULL != p)
	{
		len++;
		p=p->next;
	}
	return len;
}//ListLength_L
6)获取指定位置元素
Status GetElem_L(struct LNode * &L,int i,ElemType &e){
	//L为带头结点的单链表头指针
	//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
	struct LNode *p = L->next;//p指向第一个节点
	int j=1;//计数
	while(p != NULL && j<i)
	{
		p = p->next;//p指针后移
		j++;
	}
	if(p==NULL || j>i)
		return ERROR;
	e = p->data;
	return OK;
}//GetElem_L
7)判断两个数据元素是否相等
Status compare_equal_L(ElemType e1,ElemType e2){
	//判断两个数据元素是否相等,相等返回TRUE,否则返回FALSE
	if(e1==e2)
		return TRUE;
	else
		return FALSE;
}//compare_equal_L
8)返回L中第一个与e满足关系的compare()的数据元素的位序
Status LocateElem_L(struct LNode *&L,ElemType e,Status (*compare)(ElemType,ElemType)){
	//单链表L已存在,compare()是数据元素判定函数
	//返回L中第一个与e满足关系的compare()的数据元素的位序,若这样的数据元素不存在,则返回值为0
	struct LNode *p = L->next;//p指向第一个节点
	int i=0;//位序
	while(NULL != p)
	{
		i++;
		if(compare(e,p->data))
			return i;
		p = p->next;
	}
	return 0;
}//LocateElem_L
9)求指定元素前驱
Status PriorElem_L(struct LNode * &L,ElemType cur_e,ElemType &pre_e){
	//要求单链表存在
	//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义
	int i=0;
	struct LNode *p = L->next;
	while(NULL!=p)
	{
		i=LocateElem_L(L,cur_e,compare_equal_L);
		if(0!=i && 1!=i)
		{
			GetElem_L(L,i-1,pre_e);
			return OK;
		}
		p=p->next;
	}
	return ERROR;
}//priorElem_L
10)求指定元素后继
Status NextElem_L(struct LNode *&L,ElemType cur_e,ElemType &next_e){
	//要求单链表存在
	//若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
	int i=0;
	struct LNode *p = L->next;
	while(NULL!=p)
	{
		i=LocateElem_L(L,cur_e,compare_equal_L);
		if(i<ListLength_L(L))
		{
			GetElem_L(L,i+1,next_e);
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}//NextElem_L
11) 指定位置插入元素
Status ListInsert_L(struct LNode *&L,int i,ElemType e){
	//要求单链表存在,1<=i<=ListLength_L(L)+1
	//在第i个元素之前插入数据元素e
	struct LNode *p;
	struct LNode *newNode;
	int j;
	p = L;
	j = 0;
	while(NULL!=p && j<i-1)
	{
		//寻找第i-1个结点 
		p = p->next;
		++j; 
	 } 
	 if(NULL==p || j>i-1)
	 	 return ERROR;
	 newNode = (struct LNode *)malloc(sizeof(LNode));//生成新结点 
	 newNode->data = e;
	 newNode->next = p->next;
	 p->next = newNode;
	 return OK;
}//LIstInsert_L
12)删除指定位置元素
Status ListDelete_L(struct LNode *&L,int i,ElemType &e){
	//要求单链表存在,1<=i<=ListLength_L(L)
	//删除L的第i个元素,并用e返回其值
	struct LNode *p;
	struct LNode *del_p;
	int j;
	p = L;
	j = 0;
	while(NULL!=p || j<i-1)
	{
		p = p->next;              //寻找第i个结点,并令p指向其前驱 
		++j;
		
	 } 
	 if(NULL==p->next || j>i+1)
	 {
	 	return ERROR;
	 }
	 del_p = p->next;            //del_p指向被删除的结点
	 p->next = del_p->next;
	 e = del_p->data;
	 free(del_p);
	 del_p = NULL;
	 return e; 
}//ListDelete_L
13)调用visit()函数遍历链表
Status visit_display_L(struct LNode * &L){
	printf("%d",L->data);
	printf("\n");
	return OK;
}//visit_display_L
Status ListTraverse_L(struct LNode * &L,Status (*visit)(struct LNode * &)){
	//要求单链表存在
	//依次对L的每个元素调用函数visit(),一旦visit()失效,则操作失败,返回FALSE,否则返回TRUE
	struct LNode *p;
	p = L->next;//p指向第一个结点L->next;
	while(NULL!=p)
	{
		if(ERROR == visit(p))
		return ERROR;
		p = p->next;
	}
	return OK;
}//ListTraverse_L

发表评论

邮箱地址不会被公开。 必填项已用*标注