数据结构严蔚敏 2.19 课本37源程序

本文详细介绍了如何使用C++编写链表操作函数,包括初始化链表、在头部和尾部插入节点、删除节点、获取元素、判断链表是否为空以及遍历链表。通过实例展示了MakeNode、FreeNode、InitList等关键操作的实现和应用。
摘要由CSDN通过智能技术生成

1.lianbiao.h

#include<stdio.h>
#include<stdlib.h>
#define TRUE  1
#define FALSE 0
#define OK    1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_LEN  100
typedef int Status;
typedef int ElemType;

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

typedef struct{//链表类型 
	Link  head,tail;//分别指向线性链表中的头结点和最后一个结点 
	int len; //指示线性链表中数据元素的个数 
}LinkList;

Status MakeNode(Link &p,ElemType e);
    //分配由p指向e的结点,并返回OK;若分配失败,则返回ERROR
void FreeNode(Link &p);
    //释放P所指结点 
    
Status InitList(LinkList &L);
   //1构造一个空的线性链表 
Status DestroyList(LinkList &L);
   //2销毁线性链表L,L不再存在 
Status ClearList(LinkList &L);
   //3 将线性链表L重置为空表,并释放原链表的结点空间 
Status InsFirst(Link h,Link s);
   //4 已知h指向线性链表的头结点,将s所指结点插入在第一个结点之前 
Status DelFirst(Link h,Link &q);
   //5 已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回 
Status Append(LinkList &L,Link s);
  //6 将指针s所指的一串结点链接在线性链表L的最后一个结点
  //之后,并改变链表L的尾指针指向新的尾结点 
Status Remove(LinkList &L,Link &q);
  //7 删除线性链表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点
Status InsBefore(LinkList &L,Link &p,Link s);
  //8 已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前,
  //并修改指针p指向新插入的结点
Status InsAfter(LinkList &L, Link &p, Link s);
  //9 已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后,
  //并修改指针p指向新插入的结点  
Status SetCurElem(Link &p,ElemType e);
  //10 已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值
ElemType GetCurElem(Link p);
  //11 已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值
Status ListEmpty(LinkList L);
  //12 若线性链表L为空表,则返回TRUE,否则返回FALSE
int ListLength(LinkList L);
  //13 返回线性链表L中元素个数
Position GetHead(LinkList L);
  //14 返回线性链表L中头结点的位置
Position GetLast(LinkList L);
  //15 返回线性链表L中最后一个结点的位置
Position PriorPos(LinkList L, Link p);
  //16 已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置
  //若无前驱,则返回NULL
Position NextPos(LinkList L, Link p);
  //17  已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置
  //若无后继,则返回NULL
Status LocatePos(LinkList L,int i,Link &p);
  //18 返回p指示线性链表L中第i个结点的位置并返回OK,i值不合法时返回ERROR
Status compare(ElemType a,ElemType b);
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType));
  //19 返回线性链表L中第1个与e满足compare()判定关系的元素的位置
  //若不存在这样的元素,则返回NULL
Status visit(ElemType x);
Status ListTraverse(LinkList L,Status(*visit)(ElemType));
  //20 依次对L的每个元素调用函数visit(),一旦visit()失败,则操作失败。 

2.lianbiao.cpp

#include "lianbiao.h"

Status MakeNode(Link &p,ElemType e)
{
	p = (LNode*)malloc(1 * sizeof(LNode));
	p->data=e;
	if(p)  return OK;
	else   return ERROR;
}

void FreeNode(Link &p)
{
	free(p);
	p=NULL;
}

Status InitList(LinkList &L)
{
	L.head=(LNode*)malloc(1 * sizeof(LNode));
	L.head->next=NULL;
	L.tail=L.head;
	L.len=0;
	if(L.head)  return OK;
	else   return ERROR; 
}

Status DestroyList(LinkList &L)
{
	ClearList(L);
    free(L.head);
    L.head = NULL;
    L.tail = NULL;
    if(!L.head)  return OK;
	else   return ERROR;
}

Status ClearList(LinkList &L)
{
	Link p = L.head->next;
    while(p){
        L.head->next = p->next;
        free(p);
        p = NULL;
        L.len--;
        p = L.head->next;
    }
    if(L.head->next==NULL)  return OK;
    else   return ERROR;
}

Status InsFirst(Link h,Link s)
{
	s->next = h->next;
    h->next = s;
    return OK;
}

Status DelFirst(Link h,Link &q)
{
	q = h->next;
	Link p=h->next; 
    if(p){
        h->next = p->next;
        return OK;
    }else
        return ERROR;
}

Status Append(LinkList &L,Link s)
{
	L.tail->next = s;
    while((L.tail->next)!=NULL){
        L.len++;
        L.tail = L.tail->next;
    }
    return OK;
}

Status Remove(LinkList &L,Link &q)
{
	if(!L.head){
        printf("线性链表不存在");
        return ERROR;
	}
    q = L.head;
    while(q->next!=L.tail){
        q = q->next;
    }
    L.tail = q;
    q = q->next;
    L.tail->next = NULL;
    L.len--;
    return OK;
}

Status InsBefore(LinkList &L, Link &p, Link s)
{
    Link q = L.head;
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
    }
	while(q->next!=p){
        q = q->next;
    }
    q->next = s;
    s->next = p;
    p = s;
    L.len++;
	return OK;
}

Status InsAfter(LinkList &L, Link &p, Link s)
{
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
    }
    s->next = p->next;
    p->next = s;
    if(p==L.tail)
        L.tail = L.tail->next;
    p = s;
    L.len++;
	return OK;
}

Status SetCurElem(Link &p,ElemType e)
{
	p->data=e;
	return OK;
}

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

Status ListEmpty(LinkList L)
{
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
    }
    if(L.head->next==NULL)
        return OK;
    else
        return ERROR;
}

int ListLength(LinkList L)
{
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
	}
	return L.len;
}

Position GetHead(LinkList L)
{
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
	}
	return L.head;
}

Position GetLast(LinkList L)
{
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
    }
	return L.tail;

}

Position PriorPos(LinkList L, Link p)
{
    Link q = L.head;
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
	}
	if(p==L.head)
		return NULL;
	while(q->next!=p){
        q = q->next;
    }
	return q;
}

Position NextPos(LinkList L, Link p)
{
    if(!L.head){
        printf("线性链表不存在");
        return ERROR;
    }
	if(p==L.tail)
		return NULL;
    return p->next;
}

Status LocatePos(LinkList L,int i,Link &p)
{
    int j = 0;
    Link pt = L.head;
    while(pt&&j<i)
	{
        pt = pt->next;
        j++;
	}
	if(!pt||j>i)
		return ERROR;
	else{
		p=pt;
		return OK;
    }
}

Status compare(ElemType a,ElemType b)
{
	if(a==b)
		return OK;
	else
		return ERROR;
}

Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType))
{
    Link q = L.head->next;
    while(q->next!=NULL)
	{
		if(compare(q->data,e))
			return q;
        q = q->next;
    }
	return NULL;
}

Status visit(ElemType x)
{
    printf("%d ",x);
    return OK;
}

Status ListTraverse(LinkList L,Status(*visit)(ElemType))
{
    Link q = L.head->next;
    printf("遍历线性链表结果如下:\n");
    while(q)
	{
		if(visit(q->data))
            q = q->next;
        else
			return ERROR;
	}
	printf("\n");
    return OK;
}

3.main.cpp

#include "lianbiao.h"

int main()
{
	Link p,he,s;
	ElemType e;
	LinkList L;
	printf("%d 如果为1则构造空线性链表成功,否则不成功\n",InitList(L));
	he=L.head;
	printf("请输入要插入的第一个结点数据:");
	scanf("%d",&e); 
	MakeNode(p,e);
	printf("%d 如果为1则表示在第一个结点前插入元素成功,否则不成功\n",InsFirst(he,p));
	printf("%d 如果为1则表示第一个结点已经删除,否则删除不成功\n",DelFirst(he,p));
	printf("删除的第一个结点元素数据为%d\n",p->data);
	int n;
	printf("请输入要构建几个元素的链表:");
	scanf("%d",&n);
	printf("请输入这几个元素数据:"); 
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&e);
		MakeNode(p,e);
		p->next=NULL;
		printf("%d 如果为1表示在尾结点插入成功且链表元素个数更新,否则不成功\n",Append(L,p));
	} 
	printf("插入后元素个数为%d\n",L.len);
	e=6;
	MakeNode(s,e);
	printf("%d 如果为1表示插入在所指结点前成功,否则不成功\n",InsBefore(L,p,s));
	printf("p所指结点数据为%d\n",p->data);
	e=7;
	MakeNode(s,e);
	printf("%d 如果为1表示插入在所指结点后成功,否则不成功\n",InsBefore(L,p,s));
	printf("p所指结点数据为%d\n",p->data);
	e=7;
    printf("%d 如果为1表示用e更新p所指结点数据成功,否则不成功\n",SetCurElem(p,e)); 
	printf("p所指结点数据的值为%d\n",p->data);
	printf("p所指结点数据值为%d\n",GetCurElem(p));
    printf("线性链表长度为%d\n",ListLength(L));
    printf("线性链表头结点位置%p\n",GetHead(L));
    printf("线性链表尾结点位置%p\n",GetLast(L));
    printf("p所指结点前驱位置%p\n",PriorPos(L,p));
    p=L.head->next; 
    printf("p所指结点后继位置%p\n",NextPos(L,p));
    printf("请选择要查找的结点:"); 
    scanf("%d",&n);
    printf("%d 如果为1表示该结点查找成功,否则不成功\n",LocatePos(L,n,p));
    printf("p所指结点后继位置%p\n",p);
    n=4;
    printf("符合相等值的元素位置为%p\n",LocateElem(L,n,(*compare)));
    printf("%d 如果为1表示遍历线性链表成功,否则不成功\n",ListTraverse(L,(*visit))); 
	printf("%d 如果为1表示线性链表置空成功,否则不成功\n",ClearList(L));
	printf("%d 如果为1表示线性链表是空表,否则不是空表\n",ListEmpty(L));
	printf("%d 如果为1表示线性链表已经销毁,否则没有销毁\n",DestroyList(L)); 
	return 0;
}

运行截图

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值