从实际应用角度出发重新定于线性链表及其基本操作

本文基于严蔚敏《数据结构》C语言版,重新阐述线性链表的概念,并探讨其在C++和C语言中的实现。文章中提供的代码可能在某些情况下需要调试才能正确运行,旨在帮助读者深入理解链表的基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据严蔚敏数据结构(C语言版)第37页改写

#include<iostream>
using namespace std;

#define ElemType int

typedef struct LNode//结点
{
	ElemType data;
	struct LNode *next;
}*Link, *Position;

typedef struct//链表
{
	Link head, tail;//头结点和尾节点
	int len;//链表长度(数据元素个数)
}LinkList;

bool MakeNode(Link &p, ElemType e)
//分配由p针指向值为e的结点
{
	if (!(p = (Link)malloc(sizeof(LNode))))return false;
	p->data = e;
	return true;
}

void FreeNode(Link &p)
//释放p指向结点
{
	free(p);
}

bool InitList(LinkList &L)
//构造一个空链表
{
	L.head = L.tail = NULL;
	L.len = 0;
	return true;
}

bool DestroyList(LinkList &L)
//摧毁线性表L,L即将不再存在
{
	Link p = L.head;
	Link q;
	while (p != L.tail)
	{
		q = p->next;
		free(p);
		p = q;
	}
	free(p);
	L.len = 0;
	return true;
}

bool ClearList(LinkList &L)
//将L重置为空标,释放原链表结点
{
	if (L.head == L.tail)return true;
	Link p = L.head->next;
	Link q;
	while (p != L.tail)
	{
		q = p->next;
		free(p);
		p = q;
	}
	free(p);
	L.tail = L.head;
	L.len = 0;
	return true;
}

bool InsFirst(Link h, Link s)
//h指向线性表头结点,将s所指结点插入第一个结点之前
{
	Link p = h->next;
	p->next = s;
	s->next = p;
	return true;
}
bool DelFirst(Link h, Link &q)
//h指向链表头结点,删除第一个结点并用q返回
{
	q = h->next;
	h->next = h->next->next;
	return true;
}

bool Append(LinkList &L, Link s)
//将指针s(为开头的链表)插入线性表L的最后一个结点之后
//并改变L的尾指针
{
	L.tail->next = s;
	while (L.tail->next != NULL)
		L.tail = L.tail->next;
	return true;
}


bool ReMove(LinkList &L, Link &q)
//删除线性表L中的尾节点,并以q返回
{
	Link p = L.head->next;
	while (p->next != L.tail)
		p = p->next;
	q = L.tail;
	L.tail = p;
	return true;
}

bool InsBefore(LinkList &L, Link &p, Link s)
//已知p指向线性表L的一个结点,将s所指结点插入到p结点之前
//并修改相应指针的变化
{
	Link q = L.head;
	while (q->next != p)
		q = q->next;
	q->next = s;
	s->next = p;
	return true;
}

bool InsAfter(LinkList &L, Link &p, Link s)
//已知p指向线性表L的一个结点,将s所指结点插入到p结点之后
//并修改相应指针变化
{
	Link q = p->next;
	p->next = s;
	s->next = q;
	return true;
}

bool SetCurElem(Link &p, ElemType e)
//已知p指向线性表中的一个结点,用e修改p结点的data
{
	p->data = e;
	return true;
}

ElemType GetCurElem(Link p)
{
	return p->data;
}

bool LsitEmpty(LinkList L)
//若线性表L为空返回ture,否则返回false
{
	return L.head == L.tail ? true : false;
}

int ListLength(LinkList L)
//返回线性表L的元素个数;
{
	return L.len;
}

Position GetHead(LinkList L)
//返回线性表头结点的位置
{
	return L.head;
}
Position GetLast(LinkList L)
//返回线性表尾节点的位置
{
	return L.tail;
}

Position PriorPos(LinkList L, Link p)
//已知p指向线性表L的一个结点,返回p的前驱结点
//若没有前驱,返回NULL
{
	if (p = L.head)return NULL;
	Link q = L.head;
	while (q->next != p)
		q = q->next;
	return q;
}

Position NextPos(LinkList L, Link p)
//已知p指向线性表L的一个结点,返回p后继节点
//若没有后继,返回NULL
{
	if (p == L.tail)return NULL;
	Link q = L.head->next;
	while (q != p) q = q->next;
	return q->next;
}

bool LocatePos(LinkList L, int i, Link &p)
//用p返回线性表中第i个结点(头结点是第0个结点)的位置
{
	int n = 1;
	Link q = L.head->next;
	while (n < i)
	{
		n++;
		q = q->next;
	}
	p = q;
	return true;
}

Position LocateElem(LinkList L, ElemType e, bool(*compare)(ElemType, ElemType))
//返回线性表中第一个与e满足compare()判断关系的元素位置
//若不存在返回NULL
{
	Position p = L.head->next;
	while (!compare(p->data, e))
		p = p->next;
	return p;
}

bool ListTraverse(LinkList L, bool(*visit)())
//依次对L调用visit(),一旦visit()失败,则操作失败
{
	Link p = L.head->next;
	while (p->next != NULL && !(visit()))
		p = p->next;
	if (p->next == NULL)
		return true;
	else return false;
}

bool ListInsert(LinkList &L, int i, ElemType e)
//在带头结点的单链表L的第i个元素之前插入元素e
{
	Link p, s;
	if (!LocatePos(L, i - 1, p))return false;
	if (!MakeNode(s, e))return false;
	InsFirst(p, s);
	return true;
}

bool MergeList(LinkList &La, LinkList &Lb, LinkList &Lc)
//La,Lb非递减
//归并La,Lb到Lc,Lc也非递减
{
	Link ha, hb, pa, pb;//h头结点,p当前结点
	Link temp;
	int a, b;
	InitList(Lc);
	ha = GetHead(La); hb = GetHead(Lb);
	pa = NextPos(La, ha); pb = NextPos(Lb, hb);
	while (pa&&pb)//pa,pb非空
	{
		a = GetCurElem(pa); b = GetCurElem(pb);
		if (a <= b)
		{
			DelFirst(ha, temp); Append(Lc, temp); pa = NextPos(La, ha);
		}
		else
		{
			DelFirst(hb, temp); Append(Lc, temp); pb = NextPos(Lb, hb);
		}
	}
	if (pa) Append(Lc, pa);
	else Append(Lc, pb);
	FreeNode(ha); FreeNode(hb);
	return true;
}

int main()
{

}

有的地方不严谨,不完整,运行可能会出错。如果使用代码,请认真调试!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值