#include <stdio.h>
#include <stdlib.h> //malloc的头文件
#define OK 0
#define ERROR -1
#define MALLOC_ERROR -2
typedef int ElementType;
typedef struct node
{
ElementType data; //结点的数据
struct node *next; //结点指针
}Node;
typedef Node *PNode; //重命名结点指针类型
//头插法创建链表
int Create_List_Head(PNode *h,//指向头结点的指针(struct node **h 二级指针:获取这个地址)
ElementType data)
{
//创建一个新的结点
PNode p = (PNode)malloc(sizeof(Node)/sizeof(char));
if (p == NULL)
{
return MALLOC_ERROR;
}
//将新数据赋给新结点
p->data = data; //从右往左看,将data赋给新结点p的data
p->next = *h; //从左往右看,p-next指向*h,获取到地址
*h = p; //从左往右看,*h移动到p,因为是头插,往前推移
return OK;
}
//尾插法创建链表
int Create_List_Tail(PNode *h, ElementType data)
{
PNode node = (PNode)malloc(sizeof(Node)/sizeof(char));
if (node == NULL)
{
return MALLOC_ERROR;
}
node->data = data;
node->next = NULL;
//将node加入到链表最后,此处要考虑是否非空表
if (*h == NULL) //空表
{
*h = node;
}
else
{
PNode temp = *h;
//找最后一个结点
while (temp->next)
{
temp = temp->next; //temp移动到temp->next的位置,结点temp往前移动到最后一个
}
temp->next = node;
}
return OK;
}
//在第pos个结点处插入一个数据
int Insert_Node(PNode *h, int pos, ElementType data)
{
PNode temp = *h;
int k=1; //第一个位置
//找到第pos-1个结点
while (temp && k < pos-1)
{
temp = temp->next;
k++;
}
//非空表 若插入的位置超过链表的位置,则无效
if (temp == NULL && *h != NULL)
{
printf("给的位置无效\n");
return ERROR;
}
//新建结点
PNode node = (PNode)malloc(sizeof(Node)/sizeof(char));
if(node == NULL)
{
return MALLOC_ERROR;
}
node->data = data;
//将结点插入到链表中
if (*h == NULL || pos == 1) //插在表前
{
node->next = *h;
*h = node;
}
else
{
node->next = temp->next; //插在表中或末尾
temp->next = node;
}
return OK;
}
//将第pos个结点删除
int Delete_Node(PNode *h, int pos)
{
if (*h == NULL)
{
printf ("空表,无法删除数据\n");
}
PNode p = *h; //结点p可用来从头指针开始操作链表,让p向后移动
int k = 1; //第一个位置
while (p && k < pos-1) //找到第pos-1个结点
{
p = p->next;
k++;
}
if (p == NULL || p->next == NULL) //要删除的结点超过链表数
{
printf ("无效的结点\n");
return ERROR;
}
PNode temp = p; //需定义一个结点来保存要删除的结点
if (pos == 1)
{
*h = p->next; //p=*h;temp=p;*h=p->next
}
else
{
temp = p->next;
p->next = temp->next;
}
free(temp);
temp = NULL;
return OK;
}
//链表逆序
int Inverse_List(PNode *h)
{
//如果是空链表或者只有一个结点的链表默认为已逆序
if (*h == NULL || (*h)->next == NULL)
{
return OK;
}
PNode pre = *h; //当前结点的前一个结点:初始化为指向第一个结点的指针
PNode cur = pre->next; //当前结点:初始化为指向第二个结点的指针
PNode next = NULL; //用于保存当前结点的下一个结点指针
while(cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
//处理头指针和尾指针
(*h)->next = NULL; //原来的第一个结点现在是最后一个结点,要将其指针置空
*h = pre ; //头指针指向现在的第一个结点也就是原来的最后一个结点
return OK;
}
//查找链表中的元素,找到后返回该结点的指针
PNode Search(PNode h, ElementType data)
{
if (h == NULL)
{
return NULL;
}
PNode temp = h;
while(temp)
{
if (temp->data == data)
{
return temp;
}
temp = temp->next; //从头开始向后一个个找
}
return NULL;
}
//计算链表的长度
int ListLen(PNode h)
{
int len = 0;
while (h)
{
h = h->next;
len++;
}
return len;
}
//打印
void DisPlay(PNode head)
{
if (head == NULL)
{
printf ("该链表是空表!\n");
return;
}
PNode temp = head; //定义一个临时的结点,将头结点赋给它
while (temp) //循环,直到链表中的所有结点都遍历完
{
printf ("%4d", temp->data); //头结点中的数据
temp = temp->next; //头结点指向链表的下一个结点,再赋给临时结点
}
printf ("\n");
}
int main()
{
PNode head = NULL; //头指针
//头插法创建链表
int i = 0;
for(i = 0; i < 10; i++)
{
//头插法创建链表 9 8 7 6 5 4 3 2 1 0
//Create_List_Head(&head, i); //如果函数里没有return OK,用这句才能输出
if (Create_List_Head(&head,i) != OK)
{
return ERROR;
}
//尾插法创建链表 0 1 2 3 4 5 6 7 8 9
/* if(Create_List_Tail(&head,i) != OK)
{
return ERROR;
}
*/
}
//在第pos个结点处插入一个数据
/* if (Insert_Node(&head,1,1) != OK)
{
return ERROR;
}
DisPlay(head); */
//将第pos个结点删除
if(Delete_Node(&head,8) != OK)
{
return ERROR;
}
//将链表逆序
if (Inverse_List(&head) != OK)
{
return ERROR;
}
//查找链表中的元素,找到后返回该结点的指针
PNode p =Search(head, 7);
if (p == NULL)
{
printf ("无此结点\n");
}
else
{
printf ("node data = %d\n",p->data);
}
DisPlay(head);
//计算链表的长度
int len = ListLen(head);
printf ("len = %d\n",len);
return 0;
}
单链表(头指针)
最新推荐文章于 2024-02-03 11:05:01 发布