【数据结构】一、链表

作者:MiTu_-_

  基本数据结构

  一、链表
  二、栈
  三、队列
  四、待续…



1.顺序表

是一种用动态分配的一维数组的线性顺序表,可以随机存储。

//名称:SqList()
//功能:线性顺序表
//说明:由于线性表的长度可变,且最大存储空间随问题不同而不同,所以用动态分配的一维数组 

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

#define OK						1
#define ERROR					0
#define LIST_SIZE				100
#define LIST_INCREMENT_SIZE		20

typedef int Status;

//链表定义
typedef int LT;		//ListElemType
typedef struct {
	LT * data;			//基址 
	int length;			//当前线性表长度 
	int listsize;		//当前分配的存储容量 
} SqList;

//链表操作
Status Init_SqList(SqList * L);
Status Insert_SqList(SqList * L, int i, LT e);
Status Delete_SqList(SqList * L, int i, LT * e);
Status Traverse_SqList(SqList L);
int Locate_data(SqList L, LT e);

int main(void)
{
	int pos;
	LT e;
	SqList L;
	Init_SqList(&L);
	Insert_SqList(&L, 1, 1);
	Insert_SqList(&L, 2, 10);
//	Delete_SqList(&L, 2, &e);
	Traverse_SqList(L);
	pos = Locate_data(L, 10);

	return 0;
} 

Status Init_SqList(SqList * L)
{
	int i, n; 
	L->data = (LT *)malloc(LIST_SIZE * sizeof(LT));
	if (!L->data)
		return ERROR;
	printf("请输入链表长度:");
	scanf("%d", &n);
	printf("请输入%d个链表元素:", n);
	for (i = 0; i < n; ++i)
		scanf("%d", &L->data[i]);
	L->length = n;					//链表长度为n
	L->listsize = LIST_SIZE;
	
	return OK;
}

Status Insert_SqList(SqList * L, int n, LT e)
{
	//在线性顺序表L中第n个位置之前插入元素e,位置为 1 ~ L->length  
	LT * newbase;						//以备增加空间 
	int i;
	if (n < 1 || n > L->length + 1)
		return ERROR;
	if (L->length >= L->listsize)		//当前存储空间已满,增加分配 
	{
		newbase = (LT *)realloc(L->data, (L->listsize + LIST_INCREMENT_SIZE) * sizeof(LT));
		if (!newbase)
			return ERROR;
		L->data = newbase;
		L->listsize += LIST_INCREMENT_SIZE; 
	}
	for (i = L->length - 1; i >= n - 1; --i)	//插入位置元素之后的元素后移 
		L->data[i + 1] = L->data[i];
	L->data[n - 1] = e;
	++L->length;
	
	return OK;	
}

Status Delete_SqList(SqList * L, int n, LT * e)
{
	//在线性顺序表L中删除第n个元素,并用e返回其值,位置为 1 ~ L->length
	int i;
	if (n < 1 || n > L->length + 1)
		return ERROR;
	*e = L->data[n - 1];
	for (i = n - 1; i < L->length - 1; ++i)		//删除位置元素之后的元素前移 
		L->data[i] = L->data[i + 1];
	--L->length;
	
	return OK; 
}

Status Traverse_SqList(SqList L)
{
	int i;
	for (i = 0; i < L.length; ++i)
		printf("%d ", L.data[i]); 
}

int Locate_data(SqList L, LT e)
{
	//在线性顺序表中返回e的位置,若找到返回位置(1 ~ L.length),否则返回-1
	int i;
	for (i = 0; i < L.length; ++i)
		if (L.data[i] == e)
			return i + 1;
			
	return -1;
}

2.单链表

一种只有后继指针的线性单向链表,无法随机存取。

//名称:LinkList()
//功能:单链表
//说明:带头结点的单链表,头插法,表头数据存放链表长度 

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

#define OK						1
#define ERROR					0

typedef int Status;

//链表定义 
typedef int LT;			//ListElemType
typedef struct LNode {
	LT data;
	struct LNode * next;
} LNode, * LinkList;

//链表函数声明 
void Init_LinkList(LinkList * L);
Status Get_LinkList(LinkList L, int n, LT * e);
Status Insert_LinkList(LinkList L, int n, LT e);
Status Delete_LinkList(LinkList L, int n, LT * e);
void Traverse_LinkList(LinkList L);

int main(void)
{
	LT e;
	LinkList L;	
	Init_LinkList(&L);
	Traverse_LinkList(L);
	Get_LinkList(L, 5, &e);
	Insert_LinkList(L, 1, 9);
	Insert_LinkList(L, 7, 9);
	Traverse_LinkList(L);
	Delete_LinkList(L, 2, &e);
	printf("delete = %d\n", e);
	Traverse_LinkList(L);
	
	return 0;	
}

void Init_LinkList(LinkList * L)
{
	//使用头插法,逆序输入n个元素的值,建立带头结点的单链表L 
	int i, n;
	LNode * p;
	*L = (LNode *)malloc(sizeof(LNode));		//建立头指针 
	(*L)->next = NULL;
	(*L)->data = 0;								//头指针数据存放链表长度 
	printf("请输入链表元素的数量:");
	scanf("%d", &n);
	printf("请输入%d个链表元素:", n);
	for (i = 0; i < n; ++i)
	{
		p = (LNode *)malloc(sizeof(LNode));
		scanf("%d", &p->data);
		p->next = (*L)->next;
		(*L)->next = p;
		++(*L)->data;					//链表长度加一 
	}
}

Status Get_LinkList(LinkList L, int n, LT * e)
{
	//获得单链表L中第n个位置的元素,并用e返回其值 	(1≤n≤L->data)
	int i;
	LNode * p;
	p = L;
	if (n < 1 || n > L->data)
		return ERROR;
	for (i = 0; i < n; ++i, p = p->next);		//p指向要查找的元素
	*e = p->data;
	printf("get = %d\n", *e);
	
	return OK;
}

Status Insert_LinkList(LinkList L, int n, LT e)
{
	//在单链表L中的第n个位置之前插入元素e ( 1≤n≤L->data + 1) 
	int i;
	LNode * p, * s;
	p = L;
	s = (LNode *)malloc(sizeof(LNode));
	s->data = e;
	if (n < 1 || n > L->data + 1)
		return ERROR;
	for (i = 0; i < n - 1; ++i, p = p->next);	//p指向要插入元素的前一个元素
	s->next = p->next;
	p->next = s;
	++L->data;
	
	return OK;
}

Status Delete_LinkList(LinkList L, int n, LT * e)
{
	//在单链表L中删除第n个元素,并由e返回其值 	(1≤n≤L->data)
	int i;
	LNode * p, * s;
	p = L;
	if (n < 1 || n > L->data)
		return ERROR;
	for (i = 0; i < n - 1; ++i, p = p->next);	//p指向要删除元素的前一个元素
	s = p->next;								//s指向要删除元素
	p->next = s->next;
	*e = s->data;
	free(s);
	--L->data;
	
	return OK;
}

void Traverse_LinkList(LinkList L)
{
	int i;
	LNode * p;
	p = L->next;
	for (i = 0; i < L->data; ++i, p = p->next)
		printf("%d ", p->data);
	printf("\n");
}


3.双链表

一种有前驱指针和后继指针的线性双向链表,无法随机存取。

//名称:DuLinkList()
//功能:双链表
//说明:带头结点的双链表,头插法,表头数据存放链表长度 

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

#define OK						1
#define ERROR					0

typedef int Status;

//链表定义 
typedef int LT;			//ListElemType
typedef struct DuLNode {
	LT data; 
	struct DuLNode * prior, * next;
} DuLNode, * DuLinkList;

//链表操作
void Init_LinkList(DuLinkList * L);
Status Get_LinkList(DuLinkList L, int n, LT * e);
Status Insert_LinkList(DuLinkList L, int n, LT e);
Status Delete_LinkList(DuLinkList L, int n, LT * e);
void Traverse_LinkList(DuLinkList L);

int main(void)
{
	LT e;
	DuLinkList L;	
	Init_LinkList(&L);
	Traverse_LinkList(L);
	Get_LinkList(L, 5, &e);
	Insert_LinkList(L, 1, 9);
	Insert_LinkList(L, 7, 9);
	Traverse_LinkList(L);
	Delete_LinkList(L, 2, &e);
	printf("delete = %d\n", e);
	Traverse_LinkList(L);
	
	return 0;	
}

void Init_LinkList(DuLinkList * L)
{
	//使用头插法,逆序输入n个元素的值,建立带头结点的双链表L 
	int i, n;
	DuLNode * p;
	*L = (DuLNode *)malloc(sizeof(DuLNode));		//建立头指针 
	(*L)->prior = (*L)->next = NULL;
	(*L)->data = 0;								//头指针数据存放链表长度 
	printf("请输入链表元素的数量:");
	scanf("%d", &n);
	printf("请输入%d个链表元素:", n);
	for (i = 0; i < n; ++i)
	{
		p = (DuLNode *)malloc(sizeof(DuLNode));
		scanf("%d", &p->data);
		p->next = (*L)->next;
		p->prior = (*L);
		(*L)->next = p;
		++(*L)->data;					//链表长度加一 
	}
}

Status Get_LinkList(DuLinkList L, int n, LT * e)
{
	//获得双链表L中第n个位置的元素,并用e返回其值 
	int i;
	DuLNode * p;
	p = L;
	if (n < 1 || n > L->data)
		return ERROR;
	for (i = 0; i < n; ++i, p = p->next);		//p指向要查找的元素
	*e = p->data;
	printf("get = %d\n", *e);
	
	return OK;
}

Status Insert_LinkList(DuLinkList L, int n, LT e)
{
	//在双链表L中的第n个位置之前插入元素e ( 1≤n ≤L->data + 1) 
	int i;
	DuLNode * p, * s;
	p = L;
	s = (DuLNode *)malloc(sizeof(DuLNode));
	s->data = e;
	if (n < 1 || n > L->data + 1)
		return ERROR;
	for (i = 0; i < n - 1; ++i, p = p->next);	//p指向要插入元素的前一个元素位置
	s->prior = p;		
	s->next = p->next;
	p->next = s;	
	p->next->prior = s;
	++L->data;
	
	return OK;
}

Status Delete_LinkList(DuLinkList L, int n, LT * e)
{
	//在双链表L中删除第n个元素,并由e返回其值 	(1≤n ≤L->data)
	int i;
	DuLNode * p, * s;
	p = L;
	if (n < 1 || n > L->data)
		return ERROR;
	for (i = 0; i < n - 1; ++i, p = p->next);	//p指向删除元素的前一个元素
	s = p->next;								//s指向被删除元素
	p->next = s->next;
	s->next->prior = p; 
	*e = s->data;
	free(s);
	--L->data;
	
	return OK;
}

void Traverse_LinkList(DuLinkList L)
{
	int i;
	DuLNode * p;
	p = L->next;
	for (i = 0; i < L->data; ++i, p = p->next)
		printf("%d ", p->data);
	printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值