数据结构概述<3>链表的简单应用

今天介绍两个链表的简单应用。

1.约瑟夫问题

假设有N个人决定选出一个领导人,方法如下:所有人排成一个圆圈,按顺序数数,每次数到第M个人出局,此时,他两边的人靠拢重新形成圆圈。问题是找出哪一个人将会是最后剩下的那个人。下列程序依次读入N和M,并给出最终结果。

#include <stdlib.h>
#include <stdio.h>

typedef struct node* link;
struct node {
	int item;
	link next;
};

int main(int argc,char *argv[])
{
	int i,N = atoi(argv[1]),M = atoi(argv[2]);
	link t = malloc(sizeof *t),x = t;
	t->item = 1;
	t->next = t;
	for (i = 2;i <= N;i++) {
		x = (x->next = malloc(sizeof *x));
		x->item = i;
		x->next = t;
	}
	while (x != x->next) {
		for (i = 1;i < M;i++)
			x = x->next;
		x->next = x->next->next;
		N--;
	}
	printf("%d\n",x->item);
}

2.插入排序

前面介绍过插入排序,是用数组的方法实现的,程序很简单,用链表反而显得比较复杂。但是主要是为了熟悉链表的使用。

#include <stdlib.h>
#include <stdio.h>

typedef struct node* link;
struct node {
	int item;
	link next;
};

int main(int argc,char *argv[])
{
	int i,N = atoi(argv[1]);
	struct node heada,headb;
	link t,x,a,b,u;
	t = &heada;
	a = t;
	for (i = 0;i < N;i++) {
		t->next = malloc(sizeof *t);
		t->next->item = rand() % 100;
		t = t->next;
		t->next = NULL;
	}
	for (t = a;t->next != NULL;t = t->next)
		printf("%d  ",t->next->item);
	printf("\n");

	for (b = &headb,b->next = NULL,t = a->next;t != NULL;t = u) {
		u = t->next;
		for (x = b;x->next != NULL;x = x->next)
			if(t->item < x->next->item)
				break;
		//x->next = t;
		//x->next->next = NULL;
		t->next = x->next;
		x->next = t;
	}
	for (t = b;t->next != NULL;t = t->next)
		printf("%d  ",t->next->item);
	printf("\n");
}

上面两个例子有个很明显的问题,只是动态申请了内存,但是没有释放,实际写程序的时候千万要注意释放,这里偷个懒就没加了。

对于第二个例子,在每次插入的时候都是从链表头到尾遍历,可以考虑利用双向链表或者循环双向链表实现从链表尾到头的遍历。

时间: 2024-10-19 17:54:38

数据结构概述<3>链表的简单应用的相关文章

数据结构概述&lt;2&gt;链表的基本概念

一 链表的定义 讨论链表之前,先说线性表. 线性表是一种最常用且最简单的数据结构.一个线性表是n个数据元素的有限集合.对于一个非空的线性表,一般存在几个特征:(1)存在唯一的一个被称作"第一个"的数据元素:(2)存在唯一的一个被称为"最后一个"的数据元素:(3)除第一个之外,线性表中的每个数据元素均只有一个前驱:(4)除最后一个之外,集合中每个数据元素均只有一个后继. 最常见的线性表就是数组了.对于数组而言,每个元素的存储空间相邻,其逻辑关系上相邻的两个元素,在物理

数据结构和算法--链表一之单向链表的简单实现

链表在我们java中也是一种基础的数据结构,可以理解成是一种和数组同级的数组结构,正如我们所知,在我们使用这集合ArrayList和LinkedList的时候,总会学习底层数组实现的ArrayList和双向链表实现的LinkedList的区别.在这里,我们将要讲说的是单向链表的简单实现,让我们体会一下链表在实现增删改查的时候是怎么样的一个操作,在和前边涉及到的数组的增删改查进行对比,得到我们学习的结论,数组的增删效率低于链表结构,查改效率高于链表结构! 什么叫做单向链表,我们可以理解为一个一个节

数据结构线性表链表的C语言实现

                                                                                      数据结构线性表链表的C语言实现      说明:线性表是一种最简单的线性结构,也是最基本的一种线性结构,所以它不仅是学习中的重点,也是应用开发非常常用的一种数据结构.它可以分为顺序表和链表.它的主要操作是数据元素的插入,删除,以及排序等.接下来,本篇文章将对线性表链表的基本操作和运用进行详细的说明(包含在源代码的注释中),并给

数据结构-概述(1)

数据结构是计算机存储.组织数据的方式.数据结构是指相互之间存在一种或多种特定关系的数据元素的集合.通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率. 数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关. 通常有下列四类基本的结构: ⑴集合结构.该结构的数据元素间的关系是"属于同一个集合". ⑵线性结构.该结构的数据元素之间存在着一对一的关系. ⑶树型结构.该结构的数据元素之间存在着一对多的关系

数据结构概述&lt;3&gt;栈

栈是一种重要的数据结构,其实质也是线性表的一种.但是它只支持两种操作:插入和删除.并且,栈的特点是后进先出,也就是说,栈的操作永远在顶部,插入和删除操作只在栈的顶部进行,所以先插入的栈会堆在底下,而后插入的栈会在栈顶,进行删除的时候,是从栈顶开始,所以新插入的元素反而能优先被删除,我们称之为后进先出.而这种插入和删除操作,在栈的用语里,叫做推进(push)和弹出(pop). 举个例子来说,栈的操作有点像一个老师收上来的作业,先交的作业放在下面,后交的作业放在上面,老师在批阅的时候,总是先从上面的

[考研系列之数据结构]数据结构概述

1.脑图 2.数据结构 2.1 抽象数据类型 表示法: (D,S,P) D:数据对象 S:D上的关系集 P:对D的基本操作集 ADT格式 ADT 抽象数据类型名{ 数据对象:<数据对象定义> 数据关系:<数据对象的定义> 基本操作:<基本操作的定义> }ADT 抽象数据类型名 基本操作的格式: 基本操作名(参数表) 初始条件:<初始条件描述> 操作结构:<操作结果描述> 2.2 分类 2.2.1 按值的不同特性 原子类型的值是不能分解的,如C中基

数据结构(一) 单链表的实现-JAVA

数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数组.树这种顺序来学习数据结构这门课程把. -WH 一.单链表的概念 链表是最基本的数据结构,其存储的你原理图如下图所示 上面展示的是一个单链表的存储原理图,简单易懂,head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一

数据结构概述&lt;4&gt;队列

队列也是一种比较常用的数据结构,和栈不同的地方在于它是先进先出的,就像我们平时的排队一样. 由于队列和栈非常相似,就不详细讲述概念了,可以参考上一篇博客数据结构概述<3>栈. 和栈一样,在这里直接给出队列的接口(queue.h),以及接口的数组实现(queue1.c)和链表实现(queue2.c).分别如下: //queue.h void queue_init(int); int queue_empty(); void queue_put(int); int queue_get(); //qu

c# 单链表实现 简单示例(可复制直接运行)

最近学习数据结构,发现c# 其实和c 的链表的实现差不多的 下面是一段可直接运行的代码 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Threading; 5 6 namespace SingleLinkedList 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 13 //实例调用