数据结构—单链表的实现(c语言版)

1、线性表的单链表表示
链式存储线性表时,不需要使用地址连续的存储单元,即不要求逻辑上相邻的元素在物理位置上也相邻,它通过“链”建立起来数据元素之间的逻辑关系,因此插入和删除操作不需要移动元素,而只需要修改指针,但也会失去顺序表可随机存取的优点。

2、单链表的基本操作

函数 说明
void InitList(LinkList &L); //初始化顺序表
int Length(LinkList &L); //返回当前长度;
bool Empty(LinkList &L); //判断是否为空
void DestoryList(LinkList &L); //销毁单链表,头结点也销毁
void PrintList(LinkList &L); //按前后顺序输出线性表L的所有元素值
bool ListInsert(LinkList L, int index, LNode *e); //插入指定位置结点
bool Delete_Node(LNode *e); //删除指定结点
bool Delete_IndexNode(LinkList &L,int index); //删除指定位置结点
bool insert_TailNode(LNode *node, LNode *p); //按值查找结点
LNode *GetElem(LinkList &L, int index); //按位查找结点
bool insert_HeadNode(LNode *node, LNode *p); //对结点进行前插操作
LNode *Init_Node(int e); //根据元素值构造新的结点

3、代码

①LinkList.h

#include
#include
//带头结点的单链表
typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList;
//初始化顺序表
void InitList(LinkList &L);
//返回当前长度;
int Length(LinkList &L);
//判断是否为空
bool Empty(LinkList &L);
//销毁单链表,头结点也销毁
void DestoryList(LinkList &L);
//按前后顺序输出线性表L的所有元素值
void PrintList(LinkList &L);
//插入指定位置结点
bool ListInsert(LinkList L, int index, LNode *e);
//删除指定结点
bool Delete_Node(LNode *e);
//删除指定位置结点
bool Delete_IndexNode(LinkList &L,int index);
//按位查找结点
LNode *GetElem(LinkList &L, int index);
//按值查找结点
LNode *LocateElem(LinkList &L, int e);
//对结点进行后插操作
bool insert_TailNode(LNode *node, LNode *p);
//对结点进行前插操作
bool insert_HeadNode(LNode *node, LNode *p);
//根据元素值构造新的结点
LNode *Init_Node(int e);

②LinkList.cpp

#include"LinkList.h"
//头插法建立单链表
//插入50个数据
LinkList List_HeadInsert(LinkList &L) {
	LNode *s;
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	for (int i = 1; i <=50; i++) {
		s = (LNode*)malloc(sizeof(LNode));
		s->data = i;
		s->next = NULL;
		s->next = L->next;
		L->next = s;
	}
	return L;
}
//尾插法建立单链表
//插入50个数据
LinkList List_TailInsert(LinkList &L) {
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	LNode *s,*r=L;
	for (int i = 1; i <= 50; i++) {
		s = (LNode*)malloc(sizeof(LNode));
		s->data = i;
		r->next = s;
		r = s;
	}
	r->next = NULL;
	return L;
}
//初始化单链表
void InitList(LinkList &L) {
	//测试采用尾插法
	List_TailInsert(L);
}
//返回单链表当前长度;
int Length(LinkList &L) {
	if (L == NULL) {
		return 0;
	}
	int length = 0;
	while (L->next != NULL) {
		L = L->next;
		length++;
	}
	return length;
}

//判断链表是否为空
bool Empty(LinkList &L) {
	if (L==NULL||L->next == NULL) 
		return true;
	else return false;
}
//销毁单链表,头结点也销毁
void DestoryList(LinkList &L) {
	if (L == NULL) {
		return;
	}
	LNode *p;
	while (L) {
		p = L;
		L = L->next;
		free(p);
	}
	L = NULL;
}
//清空单链表,还剩下头结点
void ClearList(LinkList &L) {
	if (L == NULL) {
		return;
	}
	LNode *p=L->next,*q;
	while (p) {
		q = p->next;
		free(p);
		p = q;
	}
	L->next = NULL;
}
//按前后顺序输出线性表L的所有元素值
void PrintList(LinkList &L) {
	if (L== NULL) {
		return;
	}
	LNode *p=L->next;
	if (p == NULL)
		return;
	for (int i = 1; p != NULL; i++){
		printf("第%d个值为%d\n", i, p->data);
		p = p->next;
	}
}
//插入指定位置结点
bool ListInsert(LinkList L, int index, LNode *e) {
	if (index == 0) {
		return false;
	}
	LNode * p=GetElem(L, index - 1);
	if (p == NULL) {
		return false;
	}
	e->next = p->next;
	p->next = e;
	return true;
}
//对结点进行后插操作
bool insert_TailNode(LNode *node, LNode *p) {
	if (node == NULL) {
		return false;
	}
	p->next = node->next;
	node->next = p;
	return true;
}
//对结点进行前插操作,通过交换数据
bool insert_HeadNode(LNode *node, LNode *p) {
	if (node == NULL||p==NULL) {
		return false;
	}
	p->next = node->next;
	node->next = p;
	int k = node->data;
	node->data = p->data;
	p->data = k;
	return true;
}
//删除指定结点
//这里使用简便方法删除,通过交换双方的数据
bool Delete_Node(LNode *e) {
	if (e->next == NULL) {
		free(e);
		return true;
	}
	else {
		LNode *p = e->next;
		e->data = p->data;
		e->next = p->next;
		free(p);
		return true;
	}
}
//删除指定位置结点
bool Delete_IndexNode(LinkList &L, int index) {
	if (index <= 0) {
		return false;
	}
	int i = 1;
	LNode *r = L->next;
	while (r != NULL && i < index) {
		r = r->next;
		i++;
	}
	return Delete_Node(r);

}
//按位查找结点
LNode *GetElem(LinkList &L, int index){
	if (index == 0)
		return L;//返回头结点
	LNode *p = L->next;
	int i = 1;
	while (p!= NULL && i < index) {
		p = p->next;
		i++;
	}
	return p;
}
//按值查找结点
LNode *LocateElem(LinkList &L, int e){
	if (L == NULL)
		return NULL;
	LNode *p = L->next;
	while (p != NULL && p->data != e) {
		p = p->next;
	}
	return p;
}
//根据元素值构造新的结点
LNode *Init_Node(int e) {
	LNode *node = (LNode*)malloc(sizeof(LNode));
	node->data = e;
	node->next = NULL;
	return node;
}

③main函数

//单链表的测试代码
void LinkList_Test() {
	LinkList L;
	//初始化单链表
	InitList(L);
	LNode*p=Init_Node(51);
	//插入指定位置结点
	ListInsert(L, 1, p);
	//删除指定位置结点
	Delete_IndexNode(L,1);
	//对接点进行前插操作
	p = Init_Node(51);
	insert_HeadNode(L->next,p);
	//对结点进行后差操作
	p = Init_Node(50);
	insert_TailNode(L, p);
	//输出结果
	PrintList(L);
	//按位查找结点
	int index = 50;
	LNode*node=GetElem(L,index);
	printf("查找的结点序号为:%d,值为:%d\n", index, node->data);
	int length = Length(L);
	printf("当前单链表长度为:%d\n", length);
	//销毁单链表
	DestoryList(L);
	printf("销毁单链表");
	length = Length(L);
	printf("当前单链表长度为:%d\n", length);
}
//主函数
int main() {
	LinkList_Test();
	system("pause");
	return 0;
}

4、输出结果
数据结构—单链表的实现(c语言版)_第1张图片
数据结构—单链表的实现(c语言版)_第2张图片

你可能感兴趣的:(数据结构)