数据结构 严蔚敏 版 线性链表c语言实现

LinkList.h


typedef int ElemType;
typedef int Status;

typedef struct LNode {
	ElemType data;
	struct LNode * next;

}LNode,*LinkList;

//当第i个元素存在 把值 通过e返回
Status GetElem_L(LinkList, int, ElemType *);

//元素插入 2.8
Status ListInsert_L(LinkList,int ,ElemType);

//元素删除 2.9
Status ListDelete_L(LinkList ,int  ,ElemType * );

//创建 2.10
void CreateList_L(LinkList * ,int );

// 排序  归并
LinkList SortInList(LinkList L, LinkList H);

//2.11 参照排序的归并部分

LinkList.c

#include <stdlib.h>
#include<stdio.h>
#include "./LinkList.h"


//当第i个元素存在 把值 通过e返回
Status GetElem_L(LinkList L, int i, ElemType* e) {
	LinkList p;
	int j; 
	p = L;
	p = p->next;//p指向第一个结点
	j = 0; //计数
	
	//寻找第 i个位置结点
	while (p && j < i)
	{
		//p指向下一个 结点  j++;
		p = p->next;
		++j;
	};
	//第i个元素 不存在
	if (!p || j > i) {
		return -1;
	};

	//返回第i个 结点的值
	*e = p->data;

	return 0;
	
};


//元素插入
Status ListInsert_L(LinkList L, int i , ElemType e) {
	LinkList p;
	LinkList s;
	int j;
	p = L;
	j = -1; //表示头结点位置  0表示第一个结点位置

	//寻找第i-1个结点
	while (p && j < i - 1)
	{
		p = p->next;
		++j;
	};

	if (!p || j > i - 1) {
		return -1;
	};

	//生成新节点
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	//插入
	s->next = p->next;
	p->next = s;
	return 0;
};

//元素删除
Status ListDelete_L(LinkList L, int i, ElemType* e) {
	LinkList p;
	LinkList q;
	int j;
	p = L;
	j = -1; //表示头结点位置  0表示第一个结点位置

	//寻找要删除结点的前一个结点
	while (p->next && j < i - 1)
	{
		p = p->next;
		++j;
	};
	if (!(p->next) || j > i - 1) {
		return -1;
	};

	//删除
	q = p->next;//记录一下要删除 结点位置 一会 释放 

	//p的next指向q的下一个结点  
	p->next = q->next;
	*e = q->data; //将删除的结点数据返回
	//释放
	free(q);
	return  0;
};

//创建
void CreateList_L(LinkList * L, int n) {
	LinkList p;
	int  i;
	//创建一个头结点 并返回给外部使用 
	*L = (LinkList)malloc(sizeof(LNode));
	(*L)->next = NULL;

	for (i = n - 1; i >= 0; --i) {
		//生成新结点
		p = (LinkList)malloc(sizeof(LNode));

		//输入 元素值 
		scanf_s("%d", &(p->data));

		//插入 到头结点后面 -》因为每次 新 值 都是插入头结点后面   所以最后插入的在第一个位置
		p->next = (*L)->next; //当前结点的next指向原先结点
		(*L)->next = p; //头结点指向当前结点
	};
};


// 排序  归并 L不能传入头结点 需要传入L->next
LinkList SortInList(LinkList L, LinkList  H) {
	LinkList res = H;
	//递归结束条件
	if (!L || !(L->next)) {
		return L;
	}


	//计算中点  用来分链表
	LinkList slow, fast, newList,leftNode,rightNode;
	//快慢指针找中点
	slow = L;
	fast = L->next;
	while (fast && fast->next) //记录: fast && fast->next 这两个判断顺序 不能写反  如果先 判断fast->next,当fast为空时,fast->next理所当然会出现 nullprt异常
	{
		slow = slow->next;
		fast = fast->next->next;

	}

	//分割成两个链表
	newList = slow->next; //1.新链表
	slow->next = NULL; //2. 新链表结尾为null

	//递归分割
	leftNode = SortInList(L,res);
	rightNode = SortInList(newList,res);

	//归并
	while (leftNode && rightNode){
		if (leftNode->data <= rightNode->data) {

			H->next = leftNode;
			leftNode = leftNode->next;
		}else {

			H->next = rightNode;
			rightNode = rightNode->next;

		};
		H = H->next;
	};
	if (!leftNode) {
		H->next = rightNode;
	}
	if (!rightNode) {
		H->next = leftNode;
	}

	return res->next;

};


Main.c

#include <stdlib.h>
#include<stdio.h>
#include "./LinkList.h"



int main() {
	LinkList  l;
	LinkList  p;
/*	CreateList_L(&l, 3);
	ElemType e;
	GetElem_L(l, 0,&e);
	printf("%d\n", e);
	GetElem_L(l, 1, &e);
	printf("%d\n", e);
	GetElem_L(l, 2, &e);
	printf("%d\n", e);
	*/
	CreateList_L(&l, 0);
	printf("插入-------------------------------\n");
	ListInsert_L(l, 0, 1);
	ListInsert_L(l, 1, 3);
	ListInsert_L(l, 2, 2);
	ListInsert_L(l, 3, 4);
	ListInsert_L(l, 3, 8);
	ListInsert_L(l, 3, 9);
	ListInsert_L(l, 3, 6);
	
	p = l;
	while (p->next)
	{
		p = p->next;
		printf("%d\n", p->data);
	}
	printf("删除-------------------------------\n");
	ElemType r;
	ListDelete_L(l, 3, &r);
	printf("删除了:%d\n",r);

	p = l;
	while (p->next)
	{
		p = p->next;
		printf("%d\n", p->data);
	}
	printf("sort-------------------------------\n");
	SortInList(l->next, l);
	p = l;
	while (p->next)
	{
		p = p->next;
		printf("%d\n", p->data);
	}
	printf("end-------------------------------");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值