线性表之链表(单链表)
程序员文章站
2022-06-06 13:39:13
...
线性表:由n(n>=0)个相同类型数据元素组成,并且可以 在任意位置进行插入和删除数据元素操作的有限序列。
单链表:它是一种链式存储的线性表,用一组地址任意的存储单元存放线性表 的数据元素,称存储单元为一个节点。
代码实现:
list.h
#include<stdio.h>
#include<stdlib.h>
#include<cassert>
typedef int DataType;
typedef struct node
{
DataType data;
struct node* next;
}Node, *pNode, *pList;
pNode Create(DataType d); //创建链表
void PushBack(pList p_list, DataType d);//尾插
void PrintList(pList p_list);//打印
void PrintListrecur(pList p_list); //递归倒叙打印链表
void PrintListBack(pList p_list);//倒序打印
pNode Find(pList p_list, DataType x); //查找
void DeleteNohead(pNode pos);//删除无头节点的非尾节点
void InsertNohead(pNode pos,DataType d);///插入无头结点的非头结点
pNode JosephList(pList p_list); //链表环化
pNode JosepListK(pList p_list, int k);
pNode Lnverse(pList p_list);//逆置链表
pNode MergeList(pList p_list1, pList p_list2);//合并两个链表
pNode QsortMergeList(pList p_list1, pList p_list2);//合并有序两个链表之后依然有序
pNode FindMidNode(pList p_list);//查找中间节点
pNode FindThelastK(pList p_list, int k);//查找倒数第K个节点
#endif //__LIST_H__
list.c#include"List.h"
pNode Create(DataType d)//创建
{
pNode p_list = (pNode)malloc(sizeof(Node));
if (p_list == NULL)
{
return NULL;
}
p_list->data = d;
p_list->next = NULL;
return p_list;
}
void PushBack(pList p_list, DataType d)//尾插
{
pNode p1 = p_list;
pNode p2 = NULL;
p2 = (pNode)malloc(sizeof(Node));
if (p2 == NULL)
{
return;
}
while (p1->next != NULL)
{
p1 = p1->next;
}
p2->data = d;
p1->next = p2;
p2->next = NULL;
}
void PrintList(pList p_list)//打印
{
assert(p_list);
while (p_list->next != NULL)
{
printf("%d->", p_list->data);
p_list = p_list->next;
}
printf("%d->NULL\n", p_list->data);
}
//一.从尾到头打印链表
void PrintListrecur(pList p_list) //递归倒叙打印链表
{
if (p_list != NULL)
{
if (p_list->next != NULL)
{
PrintListrecur(p_list->next);
}
printf("%d->", p_list->data);
}
}
pNode l = NULL;
void PrintListBack(pList p_list) //倒序打印
{
pNode p;
p = p_list;
while (p != NULL)
{
while (p != l)
{
pNode q = NULL;
q = p;
if (q->next == l)
{
printf("%d->", p->data);
break;
}
p = p->next;
}
l = p;
if (l == p_list)
break;
p = p_list;
}
printf("\n");
}
//二.删除无头结点的非尾节点(不能遍历链表)
pNode Find(pList p_list, DataType x) //查找
{
pNode p, q;
p = p_list;
q = NULL;
while (p->next->data != x&&p->next != NULL)
{
p = p->next;
if (p->next == NULL)
{
printf("没有找到\n");
return NULL;
}
}
printf("找到了\n");
return (p = p->next);
}
void DeleteNohead(pNode pos) //删除无头节点非尾节点
{
assert(pos);
pNode ptmp1 = NULL;
pNode ptmp2 = NULL;
ptmp1 = pos->next;
ptmp2 = ptmp1->next;
DataType tmp=pos->data;
pos->data = ptmp1->data;
ptmp1->data = tmp;
pos->next = ptmp2;
ptmp1->next = NULL;
free(ptmp1);
}
//三.在无头单链表的一个非头节点前插入一个节点
void InsertNohead(pNode pos,DataType d) //插入无头结点的非头结点前
{
assert(pos);
pNode ptmp1 = NULL;
pNode ptmp2 = NULL;
ptmp2 = pos->next;
ptmp1 = (pNode)malloc(sizeof(Node));
if (ptmp1 == NULL)
return;
ptmp1->data = d;
pos->next = ptmp1;
ptmp1->next = ptmp2;
DataType tmp = pos->data;
pos->data = ptmp1->data;
ptmp1->data = tmp;
}
//四.单链表实现约瑟夫环(JosephCircle)
pNode JosephList(pList p_list) //链表环化
{
pNode p = p_list;
while (p_list->next != NULL)
{
p_list = p_list->next;
}
p_list->next = p;
return p;
}
pNode JosepListK(pList p_list, int k)
{
int i = 0;
for (i = 0; i < k - 1; i++)
{
p_list = p_list->next;
}
pNode p1 = p_list;
pNode p2 = p_list->next;
pNode p3 = p_list->next->next;
p1->next = p3;
free(p2);
if (p1->next == p1)
return p1;
JosepListK(p3, k);
}
//五.链表逆置
pNode Lnverse(pList p_list)//逆置链表
{
assert(p_list);
pNode pHead = NULL;
pNode p1 = p_list;
pNode pt = NULL;
while (p1 != NULL)
{
pNode p2 = p1->next;
if (p2 == NULL)
pHead = p1;
p1->next = pt;
pt = p1;
p1 = p2;
}
return pHead;
}
//六.合并两个有序链表, 合并后依然有序
pNode MergeList(pList p_list1, pList p_list2)//合并两个链表
{
assert(p_list1);
assert(p_list2);
pNode p = p_list1;
while (p->next != NULL)
{
p = p->next;
}
p->next = p_list2;
return p_list1;
}
pNode QsortMergeList(pList p_list1, pList p_list2)//合并有序两个链表之后依然有序
{
pNode newhead = NULL;
if ((p_list1 == NULL) && (p_list2 != NULL))
{
return p_list2;
}
if ((p_list1 != NULL) && (p_list2 == NULL))
{
return p_list1;
}
if ((p_list1->data) >= (p_list2->data))
{
newhead = p_list1;
newhead->next = QsortMergeList(p_list1->next, p_list2);
}
else
{
newhead = p_list2;
newhead->next = QsortMergeList(p_list1, p_list2->next);
}
return newhead;
}
//七.查找单链表的中间节点,要求只能遍历一次链表
pNode FindMidNode(pList p_list)//查找中间节点
{
assert(p_list);
pNode p1 = p_list;
pNode p2 = p_list;
while (p2->next->next != NULL)
{
p1 = p1->next;
p2 = p2->next->next;
if (p2->next == NULL)
{
return p1;
}
}
return p1;
}
//八.查找单链表的倒数第k个节点,要求只能遍历一次链表
pNode FindThelastK(pList p_list, int k)//查找倒数第K个节点
{
pNode p1 = p_list;
pNode p2 = p_list;
int i = 0;
for (i = 0; i < k - 1; i++)
{
p2 = p2->next;
}
while (p2->next != NULL)
{
p2 = p2->next;
p1 = p1->next;
}
return p1;
}
test.c 部分测试#include"List.h"
void test1()
{
pNode p = NULL;
p=Create(5);
PushBack(p, 4);
PushBack(p, 3);
PushBack(p, 2);
PushBack(p, 1);
PushBack(p, 0);
PrintList(p);
PrintListrecur(p);
printf("\n");
PrintListBack(p);
pNode pos=Find(p, 2);
DeleteNohead(pos);
PrintList(p);
}
void test2()
{
pNode p = NULL;
p = Create(5);
PushBack(p, 4);
PushBack(p, 2);
PushBack(p, 1);
PushBack(p, 0);
PrintList(p);
pNode pos=Find(p, 2);
InsertNohead(pos, 3);
PrintList(p);
}
int main()
{
// test1();
test2();
return 0;
}
上一篇: 实验二 线性表综合实验(双链表)
下一篇: php的chinapay扩充安装