C语言实现单向链表的新建节点、插入节点、删除节点、循环遍历输出节点、返回链表的节点个数、清空链表、返回指定位置的节点,倒置链表。。。。等等
具体见代码:
#include<stdio.h>
#include<stdlib.h>
struct MyList//单向链表
{
int data;
struct MyList *next;
};
//动态新建一个节点
struct MyList * CreateNode()
{
return calloc(sizeof(struct MyList), 1);
}
//循环遍历一个链表
void Traverse(struct MyList * ls)
{
struct MyList *p = ls;
while (p)
{
printf("%d\n", p->data);
p = p->next;
}
}
//在指定位置(相对于ls指向的位置偏移pos个位置)插入元素,并返回指向这个被插入的元素
struct MyList * Insert(struct MyList *ls,int pos, int d)
{
struct MyList *p = ls;
while (p&&pos--)
{
p = p->next;
}
if (p==NULL)
{
return NULL;//pos指定的位置大于链表的节点数
}
//新建一个节点
struct MyList *node = calloc(sizeof(struct MyList), 1);
node->data = d;
node->next = p->next;
p->next = node;
//return node;
}
//删除相对于ls指定位置的节点
int Delete(struct MyList *ls, int pos)
{
struct MyList *p = ls;
while (p&&--pos)
{
p = p->next;
}
if (p == NULL)
{
return -1;//删除的位置超过了最后一个节点,pos的位置不合理,删除失败
}
//printf(" %d ", p->data);
//两种删除方法之一:
//struct MyList *tmp = p->next->next;
//free(p->next);
//p->next= tmp;
//两种删除方法之二:
struct MyList *tmp = p->next;
p->next = tmp->next;
free(tmp);
return 0;//删除成功
}
//返回链表的元素个数
int Count(struct MyList *ls)
{
int count=0;
struct MyList *p = ls;
while (p != NULL) //等价于 while(p)
{
count++;
p = p->next;
}
return count;
}
//清空链表,只保留首节点
void Clear(struct MyList *ls)
{
struct MyList *p = ls->next;
struct MyList *p1 = ls;
while (p)//第二个节点
{
struct MyList *temp = p->next;
free(p);
p = temp;
}
p1->next = NULL;
}
int Empty(struct MyList *ls)
{
struct MyList *p = ls;
if (p->next != NULL)
return 1;//非空
else
return 0;//空
}
//返回指定位置的节点
struct MyList * Locate(struct MyList *ls,int pos)
{
struct MyList *p = ls;
while (p&&--pos)
{
p = p->next;
}
if (p == NULL)
return NULL;
return p;
}
//返回指定元素值的节点
struct MyList * GetNodeByData(struct MyList *ls, int value)
{
struct MyList *p = ls;
while (p)
{
if (value == p->data)
return p;
else
p = p->next;
}
return NULL;
}
//返回指定元素值节点的位置
int GetPosByData(struct MyList *ls, int value)
{
int index = 0;
struct MyList *p = ls;
while (p)
{
if (value == p->data)
return index;
p = p->next;
index++;
}
return -1;
}
//得到链表的最后一个节点
struct MyList * GetLastNode(struct MyList *ls)
{
struct MyList *p = ls;
while (p->next)
{
p = p->next;
}
return p;
}
//合并两个链表,不合并第二个链表的头
struct MyList * MergeList(struct MyList * list1, struct MyList *list2)
{
struct MyList *p = list1;
while (p->next)
{
p = p->next;
}
p->next = list2->next;
free(list2);//list2的链表头不要了
}
//链表的倒置
void Reverse(struct MyList *ls)
{
if (ls->next == NULL)//只有头结点
return ls;
if (ls->next->next == NULL)//只有头结点和第一个节点
return ls;
struct MyList * newlast = ls->next;//倒置后的最后一个节点(倒置前的第二个节点)
struct MyList *PPre = ls;
struct MyList *CCur = ls->next;
struct MyList *NNext = NULL;
while (CCur)
{
NNext = CCur->next;
CCur->next = PPre;
PPre = CCur;
CCur = NNext;
}
ls->next = PPre;
newlast->next = NULL;
}
int main()
{
struct MyList *l1 = CreateNode(); // calloc(sizeof(struct MyList), 1);
struct MyList *l2 = CreateNode(); // calloc(sizeof(struct MyList), 1);
struct MyList *l3 = CreateNode(); // calloc(sizeof(struct MyList), 1);
struct MyList *l4 = CreateNode(); // calloc(sizeof(struct MyList), 1);
struct MyList *l5 = CreateNode(); // calloc(sizeof(struct MyList), 1);
l1->next = l2;
l2->next = l3;
l3->next = l4;
l4->next = l5;
l5->next = NULL;
l1->data = 100;
l2->data = 200;
l3->data = 300;
l4->data = 400;
l5->data = 500;
Traverse(l1);
printf("----------------------------------\n");
Insert(l1, 2, 25);//相对于l1,偏移2个的位置插入,即在300之后插入25;
//如果Insert函数里面是--pos,则在300之前插入25;
Insert(l1, 2, 26);
Insert(l1, 2, 27);
Insert(l1, 2, 28);
//注意输入的顺序,遍历输出是:100,200,300,28,27,26,25,400,500
Traverse(l1);
printf("----------------------------------\n");
Delete(l1, 2);//删除300,注意是--pos
Traverse(l1);
printf("链表中元素的个数是:%d\n", Count(l2));//输出7,从l2开始的
printf("----------------------------------\n");
//Clear(l1);
Traverse(l1);
printf("----------------------------------\n");
struct MyList *pt=Locate(l1, 3);
printf("第%d个元素的值是%d\n",3,pt->data);
int ii = GetPosByData(l1, 28);
printf("值为28的节点的位置是:%d\n", ii);//从0开始
struct MyList *ppp = GetLastNode(l1);
printf("最后一个节点的值是:%d\n", ppp->data);
printf("----------------------------------\n");
//新建另一个链表
struct MyList * node21 = CreateNode();
struct MyList * node22 = CreateNode();
struct MyList * node23 = CreateNode();
struct MyList * node24 = CreateNode();
struct MyList * node25 = CreateNode();
node21->next = node22;
node22->next = node23;
node23->next = node24;
node24->next = node25;
node25->next = NULL;
node21->data = 2001;
node22->data = 2002;
node23->data = 2003;
node24->data = 2004;
node25->data = 2005;
//MergeList(l1, node21);
Traverse(l1);
printf("----------------------------------\n");
Reverse(l1);
Traverse(l1);
return 0;
}
效果: