首页 > 代码库 > 数据结构概述<3>链表的简单应用

数据结构概述<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");
}

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

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

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