以下是带有头节点的单链表基本操作
/*头文件及函数声明*/
#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;
}