第一章之线性表(二)链式表示

目录

单链表结点类型描述

头插法建立单链表

尾插法建立单链表

在单链表中按序号查找结点值

在单链表中按值查找结点

求表长

将值为x的节点插入到单链表的第i个位置上

将值单链表的第i个位置上的结点删除

双链表的结点类型描述

双链表的插入:在p之后插入s

双链表的删除:删除p的后继结点q

静态链表结构类型描述


单链表结点类型描述

typedef struct LNode {
	ElemType data;        //数据域
	struct LNode* next;   //指针域,指向后继
}LNode, *LinkList;       //LinkList等价于LNode*

头插法建立单链表

LinkList createListByHead(LinkList &L) {
	LNode* s;       //工作指针
	int x;          //存输入元素

	L = (LinkList)malloc(sizeof(LNode));        //创建头结点
	L->next = NULL;                             //初始为空表
	scanf("%d", &x);                            //读取输入值

	while(x != 9999) {                 //约定,输入9999表示创建结束
		s = (LNode*)malloc(sizeof(LNode));   //创建新结点
		s->data = x;                         //设置数据域

		//插入s到表头
		s->next = L->next;          //s后继设置L
		L->next = s;                //L后继设置s

		scanf("%d", &x);
	}
	return L;                       //返回头结点
}

尾插法建立单链表

LinkList createListByTail(LinkList &L) {
	int x;                 //存输入元素

	L = (LinkList)malloc(sizeof(LNode));         //创建头结点

	LNode* s,                                    //s为工作指针
		 * r = L;                                //r为表尾元素
	scanf("%d", &x);                             //读取输入值


	while (x != 9999) {           //约定,输入9999表示创建结束
		s = (LNode*)malloc(sizeof(LNode));       //创建新结点
		s->data = x;                             //设置数据域

		//插入s到表尾
		r->next = s;
		r = s;

		scanf("%d", &x);
	}
	r->next = NULL;                     //尾巴置空
	return L;                           //返回头结点
}

在单链表中按序号查找结点值

/*
* 取出单链表L(带头结点)中第i个位置的结点指针
*/
LNode* GetElemByPos(LinkList L, int i) {
	int j = 1;                   //计数,初始为1
	LNode* p = L->next;

	if (i == 0) {                //i为0,返回头结点
		return L;
	}

	if (i < 1) return NULL;      //无效的i,返回NULL

	while (p != NULL &&          //链表还没有遍历完
		j < i) {                 //还没有到达所求的结点
		p = p->next;             //指针后移
		j++;                     //计数++
	}

	return p;       //i大于表长,NULL;否则返回找到的结点
}

在单链表中按值查找结点

/*
* 从头开始遍历,返回其中数据域值为给定e的结点的指针,不存在则返回NULL
*/
LNode* locateElemByValue(LinkList L, ElemType e) {
	LNode* p = L->next;

	while (p != NULL                //表中还有元素 
		&& p->data != e) {          //还没有找到数据域的值是e的结点
		p = p->next;
	}
	return p;                       //没找到,p是NULL;找到了,就是对应结点
}

求表长

//求有头结点的单链表长度
int length(LinkList L) {
    //初始长度
	int len = 0;

    //去掉头结点
	LNode* p = L-》next;

    //每向后遍历一个,长度加1
	while (p != NULL) {
	    len++;
		p = p->next;
	}

	return j;
}

将值为x的节点插入到单链表的第i个位置上

/*
* 在L的第i个位置上插入元素值为x的结点
*/
void insertNode(LinkList L, int i, ElemType x) {
	if (i < 1 || i > length(L) + 1) {     //非法插入位置
		return ;
	}
	LNode* s = (LNode*)malloc(sizeof(LNode)); //创建一个新的结点
	s->data = x;                              //数据域赋值

	LNode* p = GetElemByPos(L, i - 1);    //找到第i个结点的前驱结点

	s->next = p->next;                    //执行插入
	p->next = s;
}

将值单链表的第i个位置上的结点删除

/*
* 删除第i个结点,并将数据域通过e返回,删除成功返回true,否则返回false
*/
bool deleteNode(LinkList L, int i, ElemType &e) {
	if (i<1 || i>length(L)) {            //删除位置非法
		return false;
	}

	LNode* p,                   //被删除结点的前驱结点
		 * q;                   //辅助指针

	p = GetElemByPos(L, i - 1); //被删除结点的前驱结点
	
	q = p->next;                //q指向需要删除的结点

	p->next = q->next;          //将需要删除的结点从链表上取下

	e = q->data;                //将值交给e

	free(q);                    //释放需要删除的结点
	return true;
}

双链表的结点类型描述

typedef struct DNode {
	ElemType data;         //数据域
	struct DNode *prior,   //前驱指针域
		         *next;    //后驱指针域
}DNode, *DLinkList;

双链表的插入:在p之后插入s

//在p之后插入s
s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;

双链表的删除:删除p的后继结点q

//删除p的后继结点q
p->next = q->next;
q->next->prior = p;
free(q);

静态链表结构类型描述

#define MaxSize 50        //静态链表的最大长度
typedef struct{
	ElemType data;        //数据域:该结点内存放的数据元素
	int next;             //指针域:下一个元素的数组下标
}SLinkList[MaxSize];

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aspect of Twilight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值