数据结构之链表

@TOC数据结构之链表(c语言)

前记

因为是机械专业学生,不像计算机专业的同学经常博客,这是我第一次写博客,排版可能会有些混乱,还望大家见谅。

学习了三天的链表,做一次总结和分享。
使用的软件是visual studio 2019

基本概念

1、线性表(Linear List):是由n(n>=0)个数据元素(结点)a1,a2,…an组成的有限序列。该序列中的所有结点具有相同的数据结构。其中数据元素的个数n称为线性表的长度。
2、顺序表:把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。用这种方法存储的线性表简称为顺序表。
3、链表:用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性表简称为线性链表。

单链表

LNode *creat_LinkList_head(void) {
/*	头插法创建单链表,链表的头结点head作为返回值 */
	int data;
	LNode* head, * p;
	head = (LNode*)malloc(sizeof(LNode));
	head->next = NULL;	/* 创建链表的表头head */
	while (1) {
		puts("输入想要保存的数据(输入32767时推出输入步骤:");
		scanf("%d", &data);
		if (data == 32767)	break;
		p = (LNode*)malloc(sizeof(LNode));
		p->data = data;
		p->next = head->next;	head->next = p;
			/* 钩链,新创建的节点总作为第一个节点 */
	}
	return(head);
}
LNode *creat_LinkList_tail(void) {
	/* 尾插入法创建单链表,链表的头结点head作为返回值*/
	int data;
	LNode* head, * p, * q;
	head = p = (LNode*)malloc(sizeof(LNode));
	p->next = NULL;		/* 创建单链表表头结点head */
	while (1) {
		puts("输入链表中的数字(输入32767时结束):");
		scanf("%d", &data);
		if (data == 32767)	break;
		q = (LNode*)malloc(sizeof(LNode));
		q->data = data;	/* 数据域赋值 */
		q->next = p->next;	p->next = q;	p = q;
		/* 钩链,新创建的结点总是作为最后一个结点 */
	}
	return(head);
}
ElemType Get_Elem(LNode* L, int i) {
	int j;	LNode* p;
	p = L->next;	j = 1;	/* 使p指向第一个结点 */
	while (p!= NULL && j < i) {
		p = p->next;	j++;	/*移动指针p,j计数 */
	}
	if (j != i)	return(-32768);
	else	return(p->data);
	/* p为NULL表示i太大;j>i表示i为0 */
}
LNode* Locate_Node(LNode* L, int key) {
	/* 在以L为头结点的单链表中查找值为key的第一个结点 */
	LNode* p = L->next;
	while (p != NULL && p->data != key)	p = p->next;
	if (p->data == key)	return p;
	else{
		printf("所要查找的结点不存在!!\n");
		return(NULL);
	}
}
void Insert_LNode(LNode* L, int i, ElemType e) {
	/* 在以L为头结点的单链表的第i个位置上插入值为e的结点 */
	int j = 0;	LNode* p, *q;
	p = L->next;	j = 1;
	while (p!=NULL && j <( i - 1)) {
		p = p->next;	j++;	/* 使p指向第一个结点 */
	}
	printf("j=%d", j);
	printf("i=%d", i);
	if (j != (i - 1))	printf("i太大或i为0!!\n");
	else {
		q = (LNode*)malloc(sizeof(LNode));
		q->data = e;	
		q->next = p->next;	p->next = q;
	}
}
void Delete_LinkList_Locate(LNode* L, int i) {
	/* 删除以L为头结点的单链表中的第i个结点 */
	int j = 0;	LNode* p, * q;
	p = L;
	q = L->next;	j = 1;
	while (p->next != NULL && j < i) {
		p = q;	 q = q->next;	j++;
	}
	if (j != i)	printf("i太大或i为0!!\n");
	else {
		p->next = q->next;	free(q);
	}
}
void Delete_LinkList_key(LNode* L, int key) {
	LNode* p = L, * q = L->next;
	while (q != NULL && q->data != key) {
		p = q;	q = q->next;
	}
	if (q->data == key) {
		p->next = q->next;	free(q);
	}
	else	printf("所要删除的节点不存在!!\n");
}
void Delete_LinkList_Node(LNode* L, int key) {
	/* 删除以L为头结点的单链表中值为key的所有结点*/
	LNode* p = L, * q = L->next;
	while (q != NULL) {
		if (q->data == key) {
			p->next = q->next; free(q);	q = p->next;
		}
		else {
			p = q;	q = q->next;
		}
	}
}
void Delete_Node_value(LNode* L) {
	/* 删除以L为头结点的单链表中所有值相同的节点 */
	LNode* p = L->next, * q, * ptr;
	while (p != NULL) {
		{
			q = p;	ptr = p->next;
			/* 检查结点p的所有后继结点ptr */
			while (ptr != NULL) {
				if (ptr->data == q->data) {
					q->next = ptr->next;	free(ptr);
					ptr = q->next;
				}
				else {
					q = ptr;	 ptr = ptr->next;
				}
			}
			p = p->next;
		}
	}
}
LNode* Merge_LinkList(LNode* La, LNode* Lb) {
	/* 合并以La,Lb为头结点的两个有序单链表 */
	LNode* Lc, * pa, * pb, * pc, * ptr;
	Lc = La;	pc = La;
	pa = La->next; pb = Lb->next;
	while (pa != NULL && pb != NULL) {
		if (pa->data < pb->data) {
			pc->next = pa;	pc = pa;	pa = pa->next;
		}
		/* 将pa所指的结点合并,pa指向下一个结点 */
		if (pa->data > pb->data) {
			pc->next = pb;	pc = pb;	pb = pb->next;
			/* 将pa所指的结点合并,pa指向下一个结点 */
		}
		if (pa->data == pb->data) {
			pc->next = pa;	pc = pa;	pa = pa->next;
			ptr = pb;	pb = pb->next;	free(ptr);
			/* 将pa所指的结点合并,pb所指结点删除*/
		}
		if (pa != NULL)	pc->next = pa;
		else	pc->next = pb;	/* 将剩余的结点链上 */
		free(Lb);
		return(Lc);
	}
}
void Printf_LinkList(LNode* L) {
	LNode* p;
	p = L->next;
	while (p != NULL) {
		printf("%d", p->data);
		p = p->next;
	}
}

双向循环链表

typedef struct Dulnode {
	ElemType data;
	struct Dulnode* prior, * next;
}DulNode;
DulNode* creat_DulLinkList_head(void) {
	/*	头插法创建单链表,链表的头结点head作为返回值 */
	int data;
	DulNode* head, * p;
	head = (DulNode*)malloc(sizeof(DulNode));
	head->next = head;	
	head->prior = head; /* 创建链表的表头head */
	while (1) {
		puts("输入想要保存的数据(输入32767时推出输入步骤:");
		scanf("%d", &data);
		if (data == 32767)	break;
		p = (DulNode*)malloc(sizeof(DulNode));
		p->data = data;
		p->next = head->next;	head->next->prior = p;
		head->next = p;		p->prior = head;	
		/* 钩链,新创建的节点总作为第一个节点 */
	}
	return(head);
}
void Printf_DulLinkList(DulNode* L) {
	DulNode* p;
	p = (DulNode*)malloc(sizeof(DulNode));
	p = L;
	while (p->next != L) {
		p = p->next;
		printf("%d ", p->data);
	}
}
DulNode* creat_DulLinkList_tail(void) {
	/* 尾插入法创建单链表,链表的头结点head作为返回值*/
	int data;
	DulNode* head, * p, * q;
	head = p = (DulNode*)malloc(sizeof(DulNode));
	p->next = p;	p->prior = p;		/* 创建循环链表表头结点head */
	while (1) {
		puts("输入链表中的数字(输入32767时结束):");
		scanf("%d", &data);
		if (data == 32767)	break;
		q = (DulNode*)malloc(sizeof(DulNode));
		q->data = data;	/* 数据域赋值 */
		q->next = p->next;	q->next->prior = p;
		p->next = q;	q->prior = p;
		p = q; 
		/* 钩链,新创建的结点总是作为最后一个结点 */
	}
	return(head);
}
ElemType Get_DulElem(DulNode* L, int i) {
	int j;	DulNode* p;
	p = L->next;	j = 1;	/* 使p指向第一个结点 */
	while (p != L && j < i) {
		p = p->next;	j++;	/*移动指针p,j计数 */
	}
	if (j != i)	return(-32768);
	else	return(p->data);
	/* p为NULL表示i太大;j>i表示i为0 */
}
DulNode* Locate_DulNode(DulNode* L, int key) {
	/* 在以L为头结点的单链表中查找值为key的第一个结点 */
	DulNode* p = L->next;
	while (p != L && p->data != key)	p = p->next;
	if (p->data == key)	return p;
	else {
		printf("所要查找的结点不存在!!\n");
		return(NULL);
	}
}
void Insert_DulLNode(DulNode* L, int i, ElemType e) {
	/* 在以L为头结点的单链表的第i个位置上插入值为e的结点 */
	int j = 0;	DulNode* p, * q;
	p = L->next;	j = 1;
	while (p != NULL && j < (i - 1)) {
		p = p->next;	j++;	/* 使p指向第一个结点 */
	}
	if (j != (i - 1))	printf("i太大或i为0!!\n");
	else {
		q = (DulNode*)malloc(sizeof(DulNode));
		q->data = e;
		q->next = p->next;	p->next->prior= q;
		p->next = q;	q->prior = p;
	}
}
void Delete_DulLinkList_Locate(DulNode* L, int i) {
	/* 删除以L为头结点的循环双向链表中的第i个结点 */
	int j = 0;	DulNode* p, * q;
	p = L;
	q = L->next;	j = 1;
	while (p->next != L && j < i) {
		p = q;	 q = q->next;	j++;
	}
	if (j != i)	printf("i太大或i为0!!\n");
	else {

		p->next = q->next;	q->next->prior = p;	free(q);
	}
}
void Delete_DulLinkList_key(DulNode* L, int key) {
	DulNode* p = L, * q = L->next;
	while (q != L && q->data != key) {
		p = q;	q = q->next;
	}
	if (q->data == key) {
		p->next = q->next;	q->next->prior = p;	free(q);
	}
	else	printf("所要删除的节点不存在!!\n");
}
void Delete_DulLinkList_Node(DulNode* L, int key) {
	/* 删除以L为头结点的循环双向链表中值为key的所有结点*/
	DulNode* p = L, * q = L->next;
	while (q != L) {
		if (q->data == key) {
			p->next = q->next;	q->next->prior = p; free(q);	q = p->next;
		}
		else {
			p = q;	q = q->next;
		}
	}
}
void Delete_DulNode_value(DulNode* L) {
	/* 删除以L为头结点的循环双向链表中所有值相同的节点 */
	DulNode* p = L->next, * q, * ptr;
	while (p != L) {
		{
			q = p;	ptr = p->next;
			/* 检查结点p的所有后继结点ptr */
			while (ptr != L) {
				if (ptr->data == q->data) {
					q->next = ptr->next;	q->next->prior = p;	free(ptr);
					ptr = q->next;
				}
				else {
					q = ptr;	 ptr = ptr->next;
				}
			}
			p = p->next;
		}
	}
}
DulNode* Merge_DulLinkList(DulNode* La, DulNode* Lb) {  
	/* 合并以La,Lb为头结点的两个有序单链表 */
	DulNode* Lc, * pa, * pb, * pc, * ptr;
	Lc = La;	pc = La;
	pa = La->next; pb = Lb->next;
	while (pa != La && pb != Lb) {

		if (pa->data < pb->data) {
			pc->next = pa;	pa->prior = pc;	 pc = pa;	pa = pa->next;
		}
		/* 将pa所指的结点合并,pa指向下一个结点 */
		if (pa->data > pb->data) {
			pc->next = pb;	pb->prior = pc;  pc = pb;	pb = pb->next;
			/* 将pa所指的结点合并,pa指向下一个结点 */
		}
		if (pa->data == pb->data) {
			pc->next = pa;	pa->prior = pc;	 pc = pa;	pa = pa->next;
			ptr = pb;	pb->prior->next = ptr->next;	pb->next->prior = pb->prior;	free(ptr);
			/* 将pa所指的结点合并,pb所指结点删除*/
		}
		if (pa != La) {

			pc->next = pa;	pa->prior = pc;
		}
		else {
			printf("hello");

			pc->next = pb;	/* 将剩余的结点链上 */
			pb->prior = pc;
			//Lb->prior->next = Lc;	Lc->prior = Lb->prior;
			while (pb ->next!= Lb) {
				pb = pb -> next;
				printf("此时pb->data=%d", pb->data);
			}
			pb->next = Lc;	Lc->prior = pb;
			free(Lb);
		}
		return(Lc);
	}
} //该函数有问题,需改变

一元多项式的表示和相加

typedef struct ploy {
	float coef;	/*系数部分*/
	int	expn;	/*指数部分*/
	struct ploy* next;
}Ploy;
Ploy* creat_ploy(void) {
	/* 尾插入法创建单链表,链表的头结点head作为返回值*/
	float coef;
	int expn;
	Ploy* head,*p,*q;
	head = p = (Ploy*)malloc(sizeof(Ploy));
	p->next = NULL;	/* 创建单链表表头head */
	while (1) {
		printf("输入系数和相应次数(输入32767 32767结束):");
		scanf("%e %d", &coef, &expn);
		//printf("coef=%e,expn=%d\n", coef, expn);
		if (coef == 32767 && expn == 32767)	break;
		else {
			q = (Ploy*)malloc(sizeof(Ploy));
			q->coef = coef;	q->expn = expn;	/*数据域赋值*/
			q->next = p->next;	p->next = q;	p = q;
			/*钩链,新创建的结点总是最后一个结点*/
		}
	}
	return(head);

}
Ploy* add_ploy_delete(Ploy* La, Ploy* Lb) {
	Ploy* Lc, * pc, * pa, * pb, * ptr;	float x;
	Lc = pc = La;	
	pa = La->next;	pb = Lb->next;
	while (pa != NULL && pb!= NULL) {
		if (pa->expn < pb->expn) {
			pc->next = pa;	pc = pa;	pa = pa->next;
			/* 将pa所指的结点合并,pa指向下一个结点 */
		}
		if (pa->expn > pb->expn) {
			pc->next = pb;	pc = pb;	pb = pb->next;
			/* 将pb所指的结点合并,pb指向下一个结点 */
		}
		else if (pa->expn = pb->expn) {
			x = pa->coef + pb->coef;
			if (abs(x) <= 1.0e-6) {
				/* 如果系数和为0,删除两个节点 */
				ptr = pa;	pa = pa->next;	free(ptr);
				ptr = pb;	pb = pb->next;	free(ptr);
			}
			else {
				pc->next = pa;	pa->coef = x;
				pc = pa;	pa = pa->next;
				ptr = pb;	pb = pb->next;	free(ptr);
			}
		}
	}	/* end of while*/
	if (pa == NULL)	pc->next = pb;
	else	pc->next = pa;
	return(Lc);
}
void Printf_polyList(Ploy* L) {
	Ploy* p;
	p = L->next;
	while (p != NULL) {
		printf("%e %d\n", p->coef,p->expn);
		p = p->next;
	}
}
Ploy* add_ploy_reserve(Ploy* La, Ploy* Lb) {
	/*将以La,Lb为头指针表示的一元多项式相加,生成一个新的结果多项式*/
	Ploy* Lc,* pc, * pa, * pb, * p;	float x;
	Lc = pc = (Ploy*)malloc(sizeof(Ploy));
	pa = La->next;	pb = Lb->next;
	while (pa != NULL && pb != NULL) {
		if (pa->expn < pb->expn) {
			p = (Ploy*)malloc(sizeof(Ploy));
			p->coef = pa->coef;	p->expn = pa->expn;
			p->next = NULL;
			/*生成一个新的结果结点并赋值*/
			pc->next = p;	pc = p;	pa = pa->next;
		}/* 生成的结点插入结果链表的最后,pa指向下一个结点 */
		if (pa->expn > pb->expn) {
			p = (Ploy*)malloc(sizeof(Ploy));
			p->coef = pb->coef;	p->expn = pb->expn;
			p->next = NULL;
			/* 生成一个新的结果结点并赋值 */
			pc->next = p;	pc = p;	pb = pb->next;
		}/* 生成的结点插入结果链表的最后,pb指向下一个结点 */
		if (pa->expn == pb->expn) {
			x = pa->coef + pb->coef;
			if (abs(x) <= 1.0e-6) {
				/* 系数和为0,pa,pb分别指向后继结点*/
				pa = pa->next;	pb = pb->next;
			}
			else {
				/* 若系数和不为0,生成的结点插入到结果链表的最后,
				pa,pb分别指向后继结点 */
				p = (Ploy*)malloc(sizeof(Ploy));
				p->coef = x;	p->expn = pb->expn;
				p->next = NULL;
				/* 生成一个新的结果结点并赋值 */
				pc->next = p;	pc = p;
				pa = pa->next;	pb = pb->next;
			}
		}
	}/* end of while */
	if (pb != NULL) {
		while (pb != NULL) {
			p = (Ploy*)malloc(sizeof(Ploy));
			p->coef = pb->coef;	p->expn = pb->expn;
			p->next = NULL;
			/* 生成一个新的结果节点并赋值*/
			pc->next = p;	pc = p;	pb = pb->next;
		}
	}
	if (pa != NULL) {
		while (pa != NULL) {
			p = (Ploy*)malloc(sizeof(Ploy));
			p->coef = pb->coef;	p->expn = pb->expn;
			p->next = NULL;
			/* 生成一个新的结果节点并赋值*/
			pc->next = p;	pc = p;	pa = pa->next;
		}
	}
	return(Lc);
}

main函数及.h文件注意事项

其他不多说了,以link.h及其main.c为例
link.h—>

#ifndef LINK_H_INCLUDE
#define LINK_H_INCLUDE

typedef	int	ElemType;
struct Lnode;
typedef struct Lnode LNode;

LNode *creat_LinkList_head(void);
LNode *creat_LinkList_tail(void);
ElemType Get_Elem(LNode* L, int i);
LNode* Locate_Node(LNode* L, int key);
void Insert_LNode(LNode* L, int i, ElemType e);
void Delete_LinkList_locate(LNode* L, int i);
void Delete_LinkList_key(LNode* L, int key);
void Delete_LinkList_Node(LNode* L, int key);
void Delete_Node_value(LNode* L);
LNode* Merge_LinkList(LNode* La, LNode* Lb);
void Printf_LinkList(LNode* L);

#endif

main->

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include<malloc.h>
#include "dullink.h"
#include "link.h"

typedef struct Lnode {
	ElemType	data; /*数据域,保存结点的值*/
	struct Lnode* next;/*指针域*/
}LNode;		/*结点的类型*/

int main()
{
	LNode* link1;
	LNode* link2;
	LNode* link3;

	link1 = creat_LinkList_head();
	Printf_LinkList(link1);

	link2 = creat_LinkList_tail();
	Printf_LinkList(link2);

	link3= Merge_LinkList(link1,link2);
	Printf_LinkList(link3);

}

希望可以坚持把数据结构学完。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值