线性结构_链表

1、定义:
n个节点离散分配;
每个节点只有一个前驱结点,每个节点只有一个后续节点;
首节点没有前驱结点,尾节点没有后续节点;

2、专业术语:
头节点:第一个有效节点之前的节点,方便对链表进行操作,并不存放有效数据,头节点的数据类型与首节点一致;
首节点:第一个有效节点;
尾节点:最后一个有效节点;
头指针:指向头节点的指针变量;
尾指针:指向尾节点的指针变量。

3、如果希望通过一个函数来对链表进行处理,我们至少需要接受链表那些信息:
只需要一个参数:头指针,通过头指针可以推算出链表的其他所有信息。

4、分类:
单链表:
双链表:每个节点有2个指针域。
循环链表:能通过任何一个节点找到所有节点。

5、算法:
遍历
查找
清空
销毁
求长度
排序
删除节点
插入节点

(要点,先临时定义一个指向p后面节点的指针r)
(在p后面插入节点q)
r = p->pNext; p->pNext = q;(p指向q) q->qNext = r;(q指向下一个节点)
q->pNext = p->pNext; p->pNext = q;

(删除p后面的节点)
r = p->pNext;
p->pNext = p->pNext->pNext;
free(r);

6、算法:
狭义的算法是与数据的存储方式密切相关的。
广义的算法是与数据的存储方式无关的。
泛型:利用某种技术达到的效果就是:不用的存储方式,执行的操作是一样的。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Node {
	int data;	//数据域
	struct Node* pNext;		//指针域,存放下一个节点的地址
} NODE , *PNODE;			//NODE相当于struct Node 类型,*PNODE想当与struct Node*类型

PNODE create_List(void);	//创建非循环单链表

void traverse_List(PNODE pHead);//遍历链表

bool is_Empty(PNODE pHead);	//判断链表是否为空

int length_List(PNODE pHead);//求链表的长度

bool insert_List(PNODE, int, int);//向链表插入数据,第一个参数是链表的头节点,第二个参数是插入的位置,第三个是插入的值(data)

bool delete_List(PNODE, int, int*);//删除某个节点,第一个参数是链表的头节点,第二个参数是删除节点的位置,第三个是删除节点的值(data)

void sort_List(PNODE);		//对链表进行排序

int main() {
	PNODE pHead = NULL;		//等价于 struct Node* pHead = null

	pHead = create_List();	//创建一个非循环单链表,并把链表首地址赋给pHead

	if (is_Empty(pHead)) {
		printf("该链表为空。\n");
	}
	else {
		printf("链表不为空。\n");
		int len = length_List(pHead);
		printf("链表的长度为:%d\n", len);
	}

	traverse_List(pHead);	//遍历链表

	sort_List(pHead);
	traverse_List(pHead);	//遍历链表

	return 0;
}

PNODE create_List(void) {
	int len;				//链表节点个数
	int val;				//用来临时存放用户输入的数据data
	//分配了一个不存放有效数据的头节点
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	if (NULL == pHead) {
		printf("分配失败,程序终止!");
		exit(-1);
	}
	//pTail与pHead都指向头节点
	PNODE pTail = pHead;
	//避免当链表节点个数为0,程序崩溃
	pTail->pNext = NULL;

	printf("请输入你要生成的链表的节点个数:");
	scanf("%d", &len);
	for (int i = 0; i < len; ++i) {
		printf("请输入第%d个节点的数据:" , i+1);
		scanf("%d", &val);
		PNODE pNew = (PNODE)malloc(sizeof(NODE));
		if (NULL == pHead) {
			printf("分配失败,程序终止!");
			exit(-1);
		}
		pNew->data = val;
		//pTali永远指向尾节点
		pTail->pNext = pNew;	//pTail指向新节点
		pNew->pNext = NULL;		//把新节点的指针域清空
		pTail = pNew;			//将新节点pNew放置到pTail
	}
	return pHead;
}


void traverse_List(PNODE pHead) {
	PNODE p = pHead->pNext;
	while (NULL != p) {
		printf("%d ", p->data);
		p = p->pNext;
	}
	printf("\n");
	return;
}

bool is_Empty(PNODE pHead) {
	if (NULL == pHead->pNext) {
		return true;
	}
	else return false;
}

int length_List(PNODE pHead) {
	PNODE p = pHead->pNext;
	int len = 0;
	while (NULL != p) {
		len++;
		p = p->pNext;
	}
	return len;
}


void sort_List(PNODE pHead) {

	/*简单的冒泡排序
	int i, j, t;
	for (i = 0; i < len - 1; i++) {
		for (j = i + 1; j < len; j++) {
			if (a[i] > a[j]) {
				t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
		}
	}
	return;*/
	int i, j, t;
	int len = length_List(pHead);
	PNODE p, q;
	for (i = 0, p = pHead->pNext; i < len - 1; i++, p = p->pNext) {
		for (j = i + 1, q = p->pNext; j < len; j++, q = q->pNext) {
			if (p->data > q->data) {
				t = p->data;
				p->data = q->data;
				q->data = t;
			}
		}
	}
	return;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值