数据结构——单链表实现及操作(c语言)

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

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1  
#define OVERFLOW -2

typedef int Status;
typedef int ElemType;

typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode, *Link, *Position;

typedef struct 
{
	Link head, tail;
	int len;
}LinkList;

Status MakeNode(Link *p, ElemType e);
void FreeNode(Link *p);
Status InitList(LinkList *L);
Status ClearList(LinkList *L);
Status Destory(LinkList *L);
Status InsertList(LinkList *L, Link s);
void Traverse(LinkList *L);
void Append(LinkList *L, Link s);
Status Remove(LinkList *L, Link q);
Status InsAfter(LinkList *L, Link *p, Link s);
Status ListCurElem(Link p, ElemType e);
Status IsEmpty(LinkList *L);
int ListLength(LinkList *L);
Position GetHead(LinkList L);
Position GetTail(LinkList L);
Position PriorPos(LinkList L, Link p);
Position NextPos(LinkList L, Link p);
Position LocatePos(LinkList L, int i, Link *p);
Status compare(ElemType e1,ElemType e2);
Position LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType));
void visit(ElemType e);
Status ListTravese(LinkList L, void (*visit)(ElemType));

void main()
{
	Link p, s, h;
	LinkList L;
	Status i;
	int j;
	Link q;
	ElemType e;
	//Status comp;
	e = 88;

	q = NULL;

	i = InitList(&L);

	if(!i)   //初始化空的线性表L不成功
		exit(-1);   //异常退出

	for(j = 1; j <= 10; j++)
	{
		MakeNode(&p, j);
		InsertList(&L, p);
	}
	Traverse(&L);

	MakeNode(&s, 9);
	s->next = NULL;   //待插入的一连串结点的尾结点
	for(j = 4; j >= 1; j--)
	{
		MakeNode(&h, j*2);
		h->next = s;
		s = h;
	}
	Append(&L, h);
	printf("After append:\n");
	Traverse(&L);
	Remove(&L, q);
	printf("The new tail pointer is %d.\n", L.tail->data);
	

	p = L.head;   //使p指向头结点
	for(i = 0; i < 3; i++)
	{
		p = p->next;
	}

	s = (Link)malloc(sizeof(LNode));
	s->data = 100;

	InsAfter(&L, &p, s);
	printf("After InsAfter:\n");
	ListCurElem(p, e);
	Traverse(&L);

	p = GetHead(L);
	printf("头结点是%d\n", p->data);
	p = GetTail(L);
	printf("尾结点是%d\n", p->data);

	p = PriorPos(L, p);
	printf("p的直接前驱是%d\n", p->data);

	p = NextPos(L, p);
	printf("p的直接后继是%d\n", p->data);

	p = LocatePos(L, 3, &p);
	printf("第三个元素的值%d\n", p->data);
	
	//comp = compare(p->next, 8);
	p = LocateElem(L, 8, compare);
	printf("第一个满足compare()判定的值为%d\n", p->data);

	ListTravese(L, visit);

	Destory(&L);
}

//分配由p指向e的结点
Status MakeNode(Link *p, ElemType e)
{
	(*p) = (Link)malloc(sizeof(LNode));
	if(!(*p)) 
		return ERROR;

	(*p)->data = e;
	return OK;
}

void FreeNode(Link *p)
{
	free(*p);
	(*p) = NULL;
}

//创造一个空的线性表
Status InitList(LinkList *L)
{
	Link p;
	p = (Link)malloc(sizeof(LNode));
	if(!p)
		return ERROR;

	p->next = NULL;
	L->head = L->tail = p;
	L->len = 0;
	return OK;
}

//将线性表L重置为空表,并释放原链表的空间
Status ClearList(LinkList *L)
{
	Link p, q;

	if(L->head != L->tail)
	{
		p = q = L->head->next;
		L->head = NULL;

		while(p < L->tail)
		{
			p = q->next;
			free(q);
			q = p;
		}

		free(q);

		L->tail = L->head;
		L->len = 0;
	}

	return OK;
}

//销毁相信链表L, L不在存在
Status Destory(LinkList *L)
{
	ClearList(L);
	FreeNode(&(L->head));   //释放头结点
	L->tail = NULL;
	L->len = 0;
	return OK;
}

//将s所指结点插入线性表
Status InsertList(LinkList *L, Link s)   
{
	
	L->tail->next = s;
	L->tail = s;
	L->len++;
	return OK;
}

void Traverse(LinkList *L)
{
	Link p;
	p = L->head->next;
	int i;

	for(i = 0; i < L->len; i++)
	{

		printf("No.%d: %d\n", i, p->data);
		p = p->next;
	}
	printf("The length of list is %d.\n", L->len);
}

//将指针s所指(彼此以指针相链)的一串结点链接在线性表L的最后一个结点
//之后,并改变链表L的指针指向新的尾结点
void Append(LinkList *L, Link s)
{
	//if(!s)
	//	exit(-1);
//	L->tail->next = s;
//	while(!L->tail->next)
//	{
	//	L->tail = L->tail->next;
//	}
	 int i=1;  
    L->tail->next = s;  //s接到L的尾部  
    while(s->next)        //计算s的长度  
    {  
        i++;  
        s = s->next;  
    }  
    L->tail = s;        //L的尾指针变成s的尾指针  
    L->len+=i;          //增加长度 
	printf("i = %d\n", i);
}

//删除线性表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点
Status Remove(LinkList *L, Link q)
{
	q = L->head->next;
	while(q->next != L->tail)
	{
		q = q->next;
	}
	free(L->tail);
	L->tail = q;
	L->len -= 1;
	return OK;
}

//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后,
//并修改指针p指向新插入的结点
Status InsAfter(LinkList *L, Link *p, Link s)
{
	s->next = (*p)->next;
	(*p)->next = s;
	
	(*p) = s;
	L->len += 1;
	
	return OK;
}

//已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值
Status ListCurElem(Link p, ElemType e)
{
	p->data = e;
	return OK;
}

//若线性表为空,则返回TRUE,否则饭后FALSE
Status IsEmpty(LinkList *L)
{
	if(!L->head->next)
		return TRUE;
	else 
		return FALSE;
}

//返回线性表元素的个数
int ListLength(LinkList *L)
{
	return L->len;
}

//返回链表L中头结点的位置
Position GetHead(LinkList L)
{
	return L.head->next;
}

//返回链表L中尾结点的位置
Position GetTail(LinkList L)
{
	return L.tail;
}

//已知p指向线性表L中的一个结点,返回p所指结点的直接前驱的位置
//若无前驱,返回NULL
Position PriorPos(LinkList L, Link p)
{
	Link q;
	q = L.head->next;
	if(p == q) return NULL;   //无前驱

	while(q->next != p)
		q = q->next;
	return q;
}

已知p指向线性表L中的一个结点,返回p所指结点的直接后继的位置
//若无后继,返回NULL
Position NextPos(LinkList L, Link p)
{
	if(!p->next)
		return NULL;
	else 
		return p->next;
}

//返回p指示链表L中第i个结点的位置并返回OK, i值不合法是返回ERROR                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
Position LocatePos(LinkList L, int i, Link *p)
{
	int j;
	if(i<L.len)
	{
		(*p)= L.head;
		for(j = 0; j < i; j++)
		{
			(*p) = (*p)->next;
		}
		return (*p);
	}

	return ERROR;
}

Status compare(ElemType e1,ElemType e2)  
{  
    return e1==e2;  
}  

//返回线性链表L中第1个与e满足函数compare()判定关系的元素的位置
Position LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType))
{
	Link p;
	p = L.head;
	do
	{
		p = p->next;
	}while(p && !compare(p->data, e) );  //找到第一个大于等于e的位置
	
	if(p ==NULL)
		return NULL;
	return p;
}

void visit(ElemType e)

{
	printf("%d  ", e);
} 

//依次对L的每个元素调用函数visit()。一旦visit()失败,则操作失败
Status ListTravese(LinkList L, void (*visit)(ElemType))
{
	Link p;
	p = L.head->next;
	int i;

	for(i = 0; i < L.len; i++)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
	return OK;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值