单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结
点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单
元,指针就是连接每个结点的地址数据。
下面是实现单链表的编程代码:
#include <stdio.h>
#include <stdlib.h>
#define OK 0
#define ERROR -1
#define MALLOC_ERROR -2
typedef int dataType ;
typedef struct node
{
dataType data ; //结点的数据
struct node * next ; // 结点指针
}Node ;
typedef Node * pNode ; //重命名结点指针类型
//头插法创建链表
int Create_List_Head(pNode * mynode ,dataType mydata)
{
//创建一个新的结点
pNode node = (pNode)malloc(sizeof(Node)/sizeof(char)) ;
if(node == NULL)
{
return MALLOC_ERROR ;
}
//将新数据赋给新的结点
node->data = mydata ;
node ->next = *mynode;
*mynode = node ;
}
//尾插法创建链表
int Create_List_Tail(pNode * mynode,dataType mydata)
{
pNode node =(pNode)malloc(sizeof(Node)/sizeof(char)) ;
if(node == NULL)
{
return MALLOC_ERROR ;
}
node->data = mydata ;
node->next = NULL ;
//将node加入到链表最后,此处要考虑是否非空表
if(*mynode == NULL)
{
*mynode = node ;
}
else
{
pNode temp = *mynode ;
//找到最后一个结点
while(temp->next)
{
temp = temp->next ;
}
temp->next = node ;
}
return OK ;
}
//在第pos个节点处插入一个数据
int Insert_Node(pNode *mynode,int nPos,dataType mydata)
{
pNode temp = *mynode ;
int k = 1 ;
//找到第pos-1个结点
while(temp && k<nPos-1)
{
temp = temp->next ;
k++ ;
}
//非空表
if(temp == NULL && *mynode!=NULL)
{
printf("给的位置无效\n") ;
return ERROR ;
}
//新建结点
pNode node = (pNode)malloc(sizeof(Node)/sizeof(char)) ;
if(node == NULL)
{
return MALLOC_ERROR ;
}
node->data = mydata ;
//将结点插入到链表中
if(*mynode == NULL || nPos == 1) //插在表头
{
node->next = *mynode ;
*mynode = node ;
}
else //插在表中或末尾
{
node->next = temp->next ;
temp->next = node ;
}
return OK ;
}
//将第pos个结点删除
int Delete_Node(pNode * mynode ,int nPos)
{
if(*mynode == NULL)
{
printf("空表,无法删除数据\n") ;
return ERROR ;
}
pNode p = *mynode ;
int k =1 ;
while(p&&k<nPos-1)
{
p = p->next ;
k++ ;
}
if(p == NULL||k>=nPos-1)
{
printf("无效的结点\n") ;
return ERROR ;
}
pNode temp = p ;
if(nPos == 1)
{
*mynode = p->next ;
}
else
{
temp = p->next ;
p->next = temp->next ;
}
free(temp) ;
}
//链表逆序
int Inverse_List(pNode * mynode)
{
//如果是空链表或者只有一个结点的链表默认为已逆序
if(*mynode == NULL ||(*mynode)->next == NULL)
{
return OK ;
}
pNode pre = *mynode ; // 当前结点的前一个结点:初始化为指向第一个结点的指针
pNode cur = pre->next ; // 当前结点:初始化为指向第二个结点的指针
pNode next = NULL ; // 用于保存当前结点的下一个结点指针
//将各个结点逆序
while(cur)
{
next = cur->next ;
cur->next = pre ;
pre = cur ;
cur = next ;
}
//处理头指针和尾结点
(*mynode)->next = NULL ; // 原来的第一个结点现在是最后一个结点 要将其指针置空
*mynode = pre ; // 头指针指向现在的第一个结点也就是原来的最后一个结点
return OK ;
}
//查找链表中的元素,找到后返回该结点的指针
pNode Search(pNode mynode,dataType mydata)
{
if(mynode == NULL)
{
return NULL ;
}
pNode temp = mynode ;
while(temp)
{
if(temp->data == mydata)
{
return temp ;
}
temp = temp->next ;
}
return NULL ;
}
//计算链表中的长度
int Len(pNode mynode)
{
int nLen = 0 ;
while(mynode)
{
mynode = mynode->next ;
nLen++ ;
}
return nLen ;
}
//打印
void Display(pNode mynode)
{
if(mynode == NULL)
{
printf("该链表是空表!\n") ;
return ;
}
pNode temp = mynode ;
while(temp)
{
printf("%4d",temp->data) ;
temp = temp->next ;
}
printf("\n") ;
}
int main()
{
pNode node = NULL;
int i = 0;
for (i = 0; i < 10; i++)
{
// 头插法创建链表
/* if (Create_List_Head(&node, i) != OK)
{
return ERROR;
} */
// 尾插法创建链表
if (Create_List_Tail(&node, i) != OK)
{
return ERROR;
}
}
Display(node);
// 在第 pos 个结点处插入一个数据
/* if(Insert_Node(&node, 1, 11) != OK)
{
return ERROR;
}
DisPlay(node); */
// 将第 pos 个结点删除
/* if(Delete_Node(&node, 1) != OK)
{
return ERROR;
}
DisPlay(node); */
// 将链表逆序
if(Inverse_List(&node) != OK)
{
return ERROR;
}
Display(node);
// 查找链表中的元素,找到后返回改结点的指针
pNode p = Search(node, 18);
if (p == NULL)
{
printf ("无此结点\n");
}
else
{
printf("node data = %d\n", p->data);
}
// 计算链表的长度
int nLen = Len(node);
printf ("len = %d\n", nLen);
return 0;
}