我的单链表的基本操作_C语言

以下是带有头节点的单链表基本操作

/*头文件及函数声明*/
#include<stdio.h>
#include<malloc.h>

#define OK 1
#define ERROR -1
typedef int Elem;
typedef int Status;

/*节点结构*/
typedef struct Node
{
	Elem data;
	struct Node *next;
}Node, *Nodep;

/*函数声明*/
Status LK_Init(Nodep *p,int n); 
Status LK_Insert(Nodep p, int n, Elem e);
Status LK_Print(Nodep p);
Status LK_Delete(Nodep p, int n);
Elem LK_Find(Nodep p, Elem e);
Status LK_Amend(Nodep p, int n, Elem e);
Status LK_Reverse(Nodep p);
/*初始化单链表*/
Status LK_Init(Nodep *p,int n) /*这里用二级指针是为了把一级指针Nope带出去*/
{
	*p = (Nodep)malloc(sizeof(Node));  //创建一个头节点,头指针*p指向它
	(*p)->data = 0;		//头节点的data用来存放节点数
	Nodep tmp = *p;		//声明一个指针指向头节点,用于遍历链表


	for(; n > 0; --n)       /*生成链表*/
	{
		Nodep a = (Nodep)malloc(sizeof(Node));
		a->data = n;   //全部初始化为0
		tmp->next = a;
		tmp = tmp->next;
		(*p)->data ++;	//节点数加1
	}
	tmp->next = NULL;
	return OK;
}

/*单链表插入元素   有头节点的*/
Status LK_Insert(Nodep p, int n, Elem e)
{
	int i = 0;
	Nodep tmp = p;
	while(tmp && i < n-1)   //此处i的值和tmp指向的节点数一样
	{
		tmp = tmp->next;
		i++;
	}
	if(!tmp)
	{
		printf("LK_Insert error.tmp = NULL\n");
		return ERROR;
	}
	if(i>n)
	{
		printf("LK_Insert error. i>n\n");
		return ERROR;
	}
	Nodep new = (Nodep)malloc(sizeof(Node));
	new->data = e;
	new->next = tmp->next;
	tmp->next = new;
	p->data++;   //节点数+1
	return OK;
}
/*打印单链表的所有数据*/
Status LK_Print(Nodep p)
{
	Nodep tmp = p;
	printf("此链表总共有 %d 个节点,各节点数据如下:\n", tmp->data);
	tmp = tmp->next;
	while(tmp)
	{
		printf("%d\t",tmp->data);
		tmp = tmp->next;
	}
	putchar('\n');
}
  /*单链表查找一个元素*/
Elem LK_Find(Nodep p, Elem e)
{	
	int pos[50];
	int count, i, k;
	Nodep tmp = p->next;
	count = 0;
	i = 1;
	k = 0;
	while(tmp)
	{
		if(tmp->data == e)
		{
			pos[count++] = i;
		}
		++i;
		tmp = tmp->next;
	}
	if(count)
	{
		printf("找到啦,总共找到 %d 个,分别在第 ", count);
		for(k=0; k<count; ++k)
			printf("%d ", pos[k]);
		printf("个节点\n");
		return OK;
	}
	else
	{
		printf("表中没有这个元素。\n");
		return ERROR;
	}
}

/*单链表删除一个元素*/
Status LK_Delete(Nodep p, int n)
{
	int i = 0;
	Nodep wtodel, tmp = p;
	while(tmp && i<n-1)   //定位到待删除元素的前一个元素
	{
		tmp = tmp->next;
		i++;
	}
	if(!tmp || i>n)
	{
		printf("Delete failed.\n");
		return ERROR;
	}
	wtodel = tmp->next;
	tmp->next = tmp->next->next;
	free(wtodel);
	p->data--;
	return OK;
}

/*修改链表的一个元素*/
Status LK_Amend(Nodep p, int n, Elem e)
{
	int i = 0;
	Nodep tmp = p;
	while(tmp && i<n)  //定位到第n个
	{
		tmp = tmp->next;
		++i;
	}
	if(!tmp || i>n)
	{
		printf("amend failed.\n");
		return ERROR;
	}
	tmp->data = e;
	return OK;
}
/*反转链表*/
Status LK_Reverse(Nodep p)
{
	Nodep one, temp;
	one = p->next;
	if(one)
		temp = one->next;
	else
	{
		printf("This linklist is null.\n");
		return ERROR;
	}
	while(temp)
	{
		one->next = temp->next;
		temp->next = p->next;
		p->next = temp;
		temp = one->next;
	}
	return OK;
}

猜你喜欢

转载自blog.csdn.net/qq_40541268/article/details/84184480