链表c语言实现

表是一种常用的数据结构,可以采用数组实现和链表实现。若采用数组实现,需要对表的大小进行事先估计,通常需要估计的大一些,从而会浪费一些空间,这是严重的局限,特别是在存在许多未知大小的表的情况下。

数组实现使得PrintList和FInd操作以线性时间执行,而FindKth(查找第K个元素)则花费常数时间。然而,插入和删除的花费则是昂贵的。例如,在位置0插入元素,首先需要将整个数组后移一个位置一空出空间来,而删除第一个元素则需要将表中的所有元素向前移动一个位置,因此这两种情形的最坏运行时间都为O(N)。因为数组实现插入和删除的运行时间如此的慢,并且还需要事先估计表的大小,所以表的实现一般都采用链表,包括单向链表,双向链表,循环链表等。

为了避免插入和删除的线性开销,需要允许表可以不连续存储,否则表的部分或全部需要整体移动。图1-1给出了链表的一般想法。


头文件:list.h

#ifndef _List_H
#define _List_H

typedef int ElementType;
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;

List MakeEmpty( List L );                             //如果L不为空,则将L的空间回收,然后重新分配空间,初始化。
int IsEmpty( List L ); 
int IsLast( Position P, List L );                    //判断P是否是最后一个元素
int Length( List L );                                //返回链表的长度
Position Find( ElementType X, List L );
void Delete( ElementType X, List L );                //删除X元素的节点
Position FindPrevious( ElementType X, List L );      //寻找X元素的前驱,如果X不存在,返回最后一个元素
void Insert( ElementType X, List L, Position P );    //在位置P之后插入元素X
void DeleteList( List L );                           //删除整个链表
Position Header( List L );
Position Advance( Position P );                      //功能就是 P = P->Next;
ElementType Retrieve( Position P );                  //功能就是 X = P->Element;
void PrintList( List L );
List Intersect( const List A, const List B);          //两个链表的交集
List Union( const List A, const List B);             //两个链表的并集
List Reverse( List L );                              //转置链表,新开辟N个元素空间             
List Reverse_constVolume( List L );                   //转置链表,但只耗费常量个元素空间
#endif

链表实现文件:list:

#include "list.h"
#include <stdlib.h>
#include <iostream>
using namespace std;

struct Node
{
	ElementType Element;
	Position Next;
};

List MakeEmpty(List L)
{
	if (L != NULL)
		DeleteList(L);
	L = (List)malloc(sizeof(struct Node));
	if (L == NULL)
		cout << "Out of memory!" << endl;
	L->Next = NULL;
	return L;
}

int IsEmpty(List L)
{
	return L->Next == NULL;
}

int IsLast( Position p, List L )
{
	return p->Next == NULL;
}

int Length( List L )
{
	Position P = L->Next;
	int len = 0;
	while (P != NULL)
	{
		++len;
		P = P->Next;
	}
	return len;
}

Position Find(ElementType X, List L)
{
	Position p;
	p = L->Next;
	while (p != NULL && p->Element != X)
		p = p->Next;
	return p;
}

void Delete( ElementType X, List L )
{
	Position p, TmpCell;
	p = FindPrevious(X, L);		//找到X的前驱,如果X不存在,那么其前驱则是表中最后一个元素

	if (!IsLast(p, L))
	{
		TmpCell = p->Next;
		p->Next = TmpCell->Next;
		free(TmpCell);
	}
}

Position FindPrevious( ElementType X, List L )
{
	Position p;
	p = L;
	while (p->Next != NULL && p->Next->Element != X)
		p = p->Next;
	return p;
}

void Insert( ElementType X, List L, Position P )
{
	Position TmpCell;
	TmpCell = (Position)malloc(sizeof(struct Node));
	if (TmpCell == NULL)
		cout << "Out of space!!!" << endl;
	
	TmpCell->Element = X;
	TmpCell->Next = P->Next;
	P->Next = TmpCell;
}

void InsertNode(PtrToNode node, List L, Position P)
{
	node->Next = P->Next;
	P->Next = node;
}

void DeleteList(List L)
{
	Position P, Tmp;
	P = L->Next;
	L->Next = NULL;
	while (P != NULL)
	{
		Tmp = P->Next;
		free(P);
		P = Tmp;
	}
}

Position Header(List L)
{
	return L;
}

Position First( List L )
{
	return L->Next;
}

Position Advance(Position P)
{
	return P->Next;
}

ElementType Retrieve( Position P )
{
	return P->Element;
}

void PrintList( List L )
{
	if (!IsEmpty(L))
	{
		Position Tmp = L->Next;
		while(Tmp != NULL)
		{
			printf("%5d", Retrieve(Tmp));
			Tmp = Advance(Tmp);
		}
		printf("\n");
	}
	else
		printf("The List is empty!!\n");
}

void Swap( Position BeforeP, List L )
{
	if (IsLast(BeforeP->Next, L))
	{
		printf("Cannot swap!\n");
		return;
	}
	Position P, AfterP;
	P = BeforeP->Next;
	AfterP = P->Next;

	BeforeP->Next = AfterP;
	P->Next = AfterP->Next;
	AfterP->Next = P;
}

List Intersect( const List A, const List B)
{
	List result = NULL;
	result = MakeEmpty(result);
	Position PA = A->Next;
	Position PB = B->Next;
	Position PR = Header(result);
	
	while (PA != NULL && PB != NULL)
	{
		if (PA->Element < PB->Element)
			PA = PA->Next;
		else if (PA->Element > PB->Element)
			PB = PB->Next;
		else
		{
			Insert(PA->Element, result, PR);
			PA = PA->Next;
			PB = PB->Next;
			PR = PR->Next;
		}
	}
	return result;
}

List Union( const List A, const List B)
{
	List result = NULL;
	result = MakeEmpty(result);
	Position PA = A->Next;
	Position PB = B->Next;
	Position PR = Header(result);


	while (PA != NULL && PB != NULL)
	{
		if (PA->Element < PB->Element)
		{
			Insert(PA->Element, result, PR);
			PA = PA->Next;
			PR = PR->Next;
		}
		else if (PA->Element > PB->Element)
		{
			Insert(PB->Element, result, PR);
			PB = PB->Next;
			PR = PR->Next;
		}
		else
		{
			Insert(PA->Element, result, PR);
			PA = PA->Next;
			PB = PB->Next;
			PR = PR->Next;
		}
	}

	if (PA == NULL)
	{
		PA = PB;
	}
	while (PA != NULL)
	{
		Insert(PA->Element, result, PR);
		PA = PA->Next;
		PR = PR->Next;
	}
	return result;
}

List Reverse( List L )
{
	int N = Length(L);
	ElementType *array = (ElementType *)malloc(sizeof(ElementType) * N);
	Position P = L->Next;
	int i = 0;
	while (P != NULL)
	{
		array[i] = P->Element;
		++i;
		P = P->Next;
	}
	
	P = L->Next;
	for (i = N - 1; i >= 0; --i)
	{
		P->Element = array[i];
		P = P->Next;
	}
	free(array);
	return L;
}

List Reverse_constVolume( List L )
{
	Position Tmp, P = L->Next;

	while (P->Next != NULL)
	{
		Tmp = P->Next;
		P->Next = Tmp->Next;
		Tmp->Next = L->Next;
		L->Next = Tmp;
	}
	return L;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值