链表(三)——链表删除冗余结点&插入结点到有序链表

1.一个以递增方式排列的链表,去掉链表中的冗余值。

思路一:设有两个指针p和q,使p不动,q依次往后循环直到p->data不等于q->data,再将中间的冗余数据删除。

思路二:设有两个指针p和q,使p在前,q在后,只要找到一个冗余就删除一个,依次往后删除。

输入的链表:1 3 3 3 3 6 6 8 9 10

删除后的链表:1 3 6 8 9 10

比较两种思路,思路二的想法相比于思路一要好,所以这里实现思路二的代码。

2.将一个结点插入到一个有序的链表中。

思路:首先要判定这个链表是递增排列的链表还是递减排列的链表,然后相对应的查找这个结点需要插入的位置。对于递增链表来说,需要查找到第一个节点值大于等于要插入的结点,然后将需要插入的结点插入到该结点前面;对于递减链表来说,需要查找到第一个小于等于要插入的结点,然后将需要插入的结点插入到该结点前面。需要考虑的特殊情况是插入的结点可能会插入在第一个位置。

#include <stdio.h>
#include <malloc.h>

#define NULL	0

typedef struct node {
	int data;
	struct node *next;
}ElemSN;

ElemSN * creat_link(int ms); //逆向创建一个链表
void print_link(ElemSN *head); //输出单向链表
void delete_rdy(ElemSN *head); //删除冗余的项
ElemSN * insert_node(ElemSN *head, int x); //插入结点到有序链表
ElemSN * clear_link(ElemSN *head); //删除链表

int main()
{
	ElemSN *head;
	int ms, x;

	printf("Please input node number:");
	scanf("%d", &ms);
	head = creat_link(ms); //创建链表
	print_link(head);
	delete_rdy(head);
	print_link(head);
	head = insert_node(head, 5);
	print_link(head);
	head = clear_link(head); //删除链表
}

ElemSN * creat_link(int ms)
{
	ElemSN *h = NULL, *p;
	int i, x;

	for(i = 0; i < ms; i++)
	{
		printf("Please input data:");
		scanf("%d", &x);
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = x;
		p->next = h;
		h = p;
	}

	return h;
}

void print_link(ElemSN *head)
{
	for(; head; head = head->next)
	{
		printf("%d ", head->data);
	}
	printf("\n");
}

void delete_rdy(ElemSN *head)
{
	ElemSN *p, *q;

	if(NULL == head)
		return;
	p = head;
	q = p->next;
	while(q)
	{
		if(p->data == q->data)
		{
			p->next = q->next;
			free(q);
			q = p->next;
		}
		else
		{
			p = q;
			q = p->next;
		}
	}
}

ElemSN * insert_node(ElemSN *head, int x)
{
	ElemSN *p, *q;

	if(NULL == head || NULL == head->next)
		return NULL;
	p = head;
	q = head; //这里不能赋值为head->next,比较必须从第一个结点开始
	if(q->data >= q->next->data) //递减链表
	{
		for(; q && q->data >= x; p = q, q = q->next){}
	}
	else //递增链表
	{
		for(; q && q->data <= x; p = q, q = q->next){}
	}

	if(NULL == q) //插入在链表尾部
	{
		q = (ElemSN *)malloc(sizeof(ElemSN));
		q->data = x;
		q->next = NULL;
		p->next = q;
	}
	else if(q == head) //插入在表首
	{
		q = (ElemSN *)malloc(sizeof(ElemSN));
		q->data = x;
		q->next = head;
		head = q;
	}
	else //插入在中间位置
	{
		p->next = (ElemSN *)malloc(sizeof(ElemSN));
		p->next->next = q;
		p->next->data = x;
	}

	return head;
}

ElemSN * clear_link(ElemSN *head)
{
	ElemSN *p;

	while(head)
	{
		p = head->next;
		free(head);
		head = p;
	}

	return head;
}
时间: 2024-12-14 18:11:17

链表(三)——链表删除冗余结点&插入结点到有序链表的相关文章

C语言实现非循环双链表节点的删除(不带头结点)

不带头结点的非循环双链表在删除节点的时候比价麻烦,因为同时要维护prior和next两个指针.在处理第一个节点和最后一个节点的时候都要分别考虑,同时也需要考虑节点数量为1的情况.删除情况分为下面两类: (1)删除pos位置的节点: (2)判断x是否在链表中,若存在则删除: 代码上传至 https://github.com/chenyufeng1991/DeleteNodeDoubleList  . 核心代码如下: //删除pos位置的节点 Node *deletePosList(Node *pN

链表(三)——链表删除冗余结点&amp;amp;插入结点到有序链表

1.一个以递增方式排列的链表,去掉链表中的冗余值. 思路一:设有两个指针p和q.使p不动,q依次往后循环直到p->data不等于q->data,再将中间的冗余数据删除. 思路二:设有两个指针p和q,使p在前,q在后,仅仅要找到一个冗余就删除一个,依次往后删除. 输入的链表:1 3 3 3 3 6 6 8 9 10 删除后的链表:1 3 6 8 9 10 比較两种思路.思路二的想法相比于思路一要好.所以这里实现思路二的代码. 2.将一个结点插入到一个有序的链表中. 思路:首先要判定这个链表是递增

C语言实现单链表节点的删除(带头结点)

我在之前一篇博客<C语言实现单链表节点的删除(不带头结点)>中具体实现了怎样在一个不带头结点的单链表的删除一个节点,在这一篇博客中我改成了带头结点的单链表.代码演示样例上传至 https://github.com/chenyufeng1991/DeleteLinkedList_HeadNode.删除类型有两种: (1)删除某个位置pos的节点: (2)推断x值是否在链表中,若存在则删除该节点: 核心代码例如以下: //删除某个位置pos的节点 Node *DeletePosNode(Node

C语言实现非循环双链表节点的删除(带头结点尾结点)

我在之前一篇博客<C语言实现非循环双链表节点的删除(不带头结点)>中详细讲解了不含头尾节点的双链表中删除一个节点,处理过程还是稍显麻烦.自从我们学习使用头尾节点来处理双链表后,删除过程就非常方便.代码上传至 https://github.com/chenyufeng1991/DeleteNodeDoubleLinkedList_HeadList . 核心代码如下: //删除pos位置的节点 int DeletePosList(Node *pHead,Node *pTail,int pos){

LeetCode-合并两个有序链表

.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 } .todo { font-family: monospace; color: red } .done { font-family: monospace; color: green } .priority { font-fami

链表(二)——单向链表的基本操作(创建、删除、打印、结点个数统计)

1.指针的联动 通过两个指针分别指向前驱和后继结点,并在单向链表上进行移动,当指针指向待处理的结点时,该结点的前驱也有指针指向. 2.设有一个无序单向链表,且数据域的值均不相同,使指针pmin指向最小值结点,并使指针prem指向最小值结点的前驱结点: 代码片段: for(p = head; p; q = p, p = p->next) { if(pmin->data > p->data) { pmin = p; prem = q; } } 3.单向链表的删除算法 注:使用mallo

给定一个链表,删除链表的倒数第 n 个节点(已知该结点存在),并且返回链表的头结点。

思路: 找到倒数第n个结点的前一个结点,让该结点的后继为倒数第n个结点的后继 子问题:找到倒数第n个结点的前驱 1.有两个引用,第一个引用指向首节点,然后走n步 2.第二个结点指向首节点,此时两结点之间隔了n-1个结点,保持这样的距离,共同向后移动 3.当第一个引用到达尾节点时,第二个引用离尾节点有n-1个结点, 4.此时第二个结点为倒数第n+1个结点,即倒数第n个结点的前驱 特殊情况: 1.链表只有一个结点或者为空链表,直接返回空即可: 2.链表的长度刚好等于n,即删除首节点,第一个引用从头结

剑指offer56:删除链表中重复的结点,排序的链表中,删除重复的结点不保留,返回链表头指针。 例如,链表1-&gt;2-&gt;3-&gt;3-&gt;4-&gt;4-&gt;5 处理后为 1-&gt;2-&gt;5

1 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 2 思路和方法 (1)链表为空,不必多说,return NULL: (2)如果恰恰是头结点与头结点的后一个重复了,这种情况是可以发生的,那头结点就要被删除,另选新的结点作为头结点.如何处理这种特殊情况,多申请一个指针就可以了. 3 C++核心代码 1 /* 2 struct

师--链表的结点插入

师--链表的结点插入 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给出一个只有头指针的链表和 n 次操作,每次操作为在链表的第 m 个元素后面插入一个新元素x.若m 大于链表的元素总数则将x放在链表的最后. Input 多组输入.每组数据首先输入一个整数n(n∈[1,100]),代表有n次操作. 接下来的n行,每行有两个整数Mi(Mi∈[0,10000]),Xi. Output 对于每组数据.从前到后输出链表的所