1.12 线性表的链式存储结构(C语言)

线性表链式表示和实现:初始化及查找、插入、删除的实现

线性表链式实现

  • 用一组任意的存储单元存储线性表的数据元素(这组数据存储单元可以是连续的,也可以不连续)
#include <stdio.h>
#include <stdlib.h>
#define ERROR NULL

typedef struct LNode *PtrToLNode;
struct LNode {
	int Data;
	PtrToLNode Next;
};
typedef PtrToLNode Position;//后面是别名
typedef PtrToLNode List;


/* 初始化线性表 */
PtrToLNode  MakeEmpty( )
{
	PtrToLNode L;
	L = (List)malloc(sizeof(LNode)); /* 产生头结点,并使L指向此头结点 */
	if (!L) /* 存储分配失败 */
		return 0;
	L->Next = NULL; /* 指针域为空 */

	return L;
}

//表的创建(头插法:将新创建的结点添加到链表的第一个数据结点之前,作为链表新的首个数据结点)
void CreateList_L1(List &L, int m[], int n){   //此处&为引用,会改变原来值
	List p;
	int i = 0;
	//逆位序输入n个元素的值,建立带表头结点的单链线性表L
	L = (List)malloc(sizeof(LNode));
    L->Next = NULL;          /*初始化定义头节点,
							 表示头节点的下一个节点为空,
							 就是该链表只有一个头节点*/

	for (i = 0; i < n; i++) {
		p = (List)malloc(sizeof(LNode));
		p->Data = m[i];  //首先将插入位置之后的链表链接到新结点p上
		//scanf("%d", &p->Data); //输入元素值	
//插入到表头
		p->Next = L->Next;  /* 修改新节点的指针域,使其指向头节点*/
		L->Next = p;   //修改头结点的指点域,使其指向新节点p
	}
}

//表的创建(尾插法:把新来的节点插入到上一个尾部,把最后一个节点的next值赋为空)
void CreateList_L2(List &L, int m[], int n) {
	List p,r; //结构体指针
	int i = 0;
	//逆位序输入n个元素的值,建立带表头结点的单链线性表L
	L = (List)malloc(sizeof(LNode));
	
	r = L;//定义一个指针,记录每次插入变换后的最后一个节点的指针域信息
	for (i = 0; i < n; i++) {
		p = (List)malloc(sizeof(LNode));
		p->Data = m[i];
		r->Next = p; //将 r(当前还是代表头节点的地址)的下一个节点指向p
		r = p;       //将原本表示头部节点地址的指针赋值为新插入的节点,表示当前节点
	
	}
	r->Next = NULL;          /*建立一个带头结点的单链表*/
}


/*求表长*/
int length(List PtrL) {
	List p = PtrL;  /*p指向表的第一个节点*/
	int j = 0;
	while (p) {
		p = p->Next; 
		j++;  /*当前p指向表的第j个节点*/
	}
	return j;
}


/* 按值查找 */
int Find(int X, List &L )
{
	List p = L->Next; /* p指向L的第1个结点 */
	while (p && p->Data != X)
		p = p->Next;
	if (p)
		return p->Data;
	else
		return ERROR;
}

/* 按序号查找 */
int Find2(int K, List &PtrL) {
	List p = PtrL;
	int i = 0;
	while (p != NULL && i < K) {
		p = p->Next;
		++i;
	}
	if (i == K) return p->Data;
	/*找到第K个,返回数据*/
	else  return NULL;
	/*否则返回NULL*/
}

/*插入*/
int Insert(List &L, int i,int e ) {
	//在含头节点的单链线性表L中第i个位置之前插入元素e
	List p = L;
	int j = 0;
	while (p&&j < i - 1) { //寻找第i-1个结点
		p = p->Next; ++j;
	}
	if (!p || j > 1 - 1) {  //i小于1或者大于表长+1   
		printf("参数i错");
        return ERROR;  
	}             
	List s = (List)malloc(sizeof(struct LNode)); /*申请、填装,生成新结点*/
	s->Data = e;       
	s->Next = p->Next; //插入L中,新结点插入在第i-1个结点的后面
	p->Next = s;

	return 0;
}

/* 删除 */
int Delete(List &L, int i)
{
	//在含有头结点的单链线性表PtrL中,删除第i个元素
	List p = L;
	int j = 0;
	while (p->Next&&j < i - 1) { //寻找第i-1个结点,并令p指向其前趋
		p = p->Next; ++j;
	}
	if (!p->Next || j > i - 1) {  //删除位置不合理  
		printf("第%d个结点不存在", i - 1);
		return ERROR;
	}

	List q = (List)malloc(sizeof(struct LNode)); /*申请、填装,生成新结点*/
	q = p->Next;       /*q指向第i个结点*/
	p->Next = q->Next;  
	free(q);	    /*删除并释放结点*/

	return 0;
}

void output(List L) {
	List p;
	p = L;
	printf("此时PtrL线性表元素为\n");
	p = L->Next;
	while (p) {
		printf("%d ", p->Data);
		p = p->Next;
	}
	printf("\n");
}

int main() {
	List PtrL;//结构体指针 
	int p1, p2;
	p1 = 0;
	p2 = 0;
	int i = 0;
	int m[100];

	for (i = 0; i < 5; i++) { 
		scanf("%d", &m[i]);
	}
    CreateList_L2(PtrL,m, 5);

	printf("PtrL->Data大小为%d位\n", sizeof(PtrL->Data) / sizeof(int));
	printf("PtrL->Data长度共%d位(包含\\0位)\n", length(PtrL));
	output(PtrL);

	printf("第1位插入1000\n");
	Insert(PtrL,1,1000 );
	printf("PtrL->Data长度共%d位(包含\\0位)\n", length(PtrL));
	output(PtrL);

	printf("删除第2位\n");
	Delete(PtrL,2);//删除第2位
	printf("PtrL->Data长度共%d位(包含\\0位)\n", length(PtrL));
	output(PtrL);

	printf("查找4的位置\n");
	p1= Find(4, PtrL);
	printf("4在PtrL第%d位\n", p1);
	printf("查找第1位\n");
	p2 = Find2(1, PtrL);
	printf("第1位在PtrL为%d\n", p2);

	return 0;
}



运行

1 2 3 4 5
PtrL->Data大小为1位
PtrL->Data长度共6(包含\0)
此时PtrL线性表元素为
1 2 3 4 51位插入1000
PtrL->Data长度共7(包含\0)
此时PtrL线性表元素为
1000 1 2 3 4 5
删除第2位
PtrL->Data长度共6(包含\0)
此时PtrL线性表元素为
1000 2 3 4 5
查找4的位置
4在PtrL第4位
查找第1位
第1位在PtrL为1000

双向链表插入结点

在这里插入图片描述

双向链表删除结点

在这里插入图片描述

最后再释放结点free(p);

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

吃鱼从来不吐刺

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

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

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

打赏作者

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

抵扣说明:

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

余额充值