单链表的创建、计数打印、删除节点、增加节点、逆序操作与查找中间节点,是上上一篇的补充,gcc调试通过。
#include<stdio.h>
#include<stdlib.h> /*使用到其中的malloc和exit函数*/
#define times 4 /*用于循环次数的控制*/
static int N=4; /*静态全局变量,用于控制单链表长度*/
typedef struct _person
{
char name[12];
int age;
struct _person *next;
}stud;
stud *Create(int num) /*创建单链表的函数,num为单链表的长度*/
{
int i;
stud *h,*p,*q; /* h为头指针,指向单链表的第一个节点*/
h=(stud*)malloc(sizeof(stud));
if(h!=NULL)
{
p=h;
for(i=0;i<num;i++)
{
q=(stud*)malloc(sizeof(stud)); /* q为指向新建节点的指针*/
if(q!=NULL)
{
printf("依次输入第%d个人的姓名和年龄:\n",i+1);
scanf("%s%d",q->name,&q->age);
q->next=NULL; /*创建新节点完毕*/
p->next=q;
p=q;
}
}
}
printf("\n");
return(h);
}
stud *Delete(stud *person,int post) /*删除单链表指定位置节点的函数*/
{
int i;
stud *cur,*pre;
cur=person;
if(0==post) /*如果输入的值为0,则不删除任何节点*/
{
printf("\n注意:您决定不删除任何节点!!!\n\n");
return(person);
}
else if(post>N||post<0) /*如果输入的值大于单链表长度或者小于0,程序结束*/
{
printf("输入有误,程序终止。\n");
exit(1);
}
else
{
if(1==post) /*在单链表头部删除的情况*/
{
cur=cur->next;
person->next=cur->next;
free(cur);
}
else /*在其它位置删除的情况*/
{
for(i=2;i<post+1;i++) /*使pre成为要插入位置的上一位置的节点*/
{
cur=cur->next;
pre=cur;
}
cur=cur->next;
pre->next=cur->next;
free(cur);
}
return(person);
}
}
stud *Insert(stud *person,int post) /*在单链表指定位置插入新的节点的函数*/
{
int i;
stud *cur,*pre,*node;
if(post>N+1||post<1) /*如果输入的值大于单链表长度加1或者小于1,程序结束*/
{
printf("输入错误,程序终止。\n");
exit(1);
}
if(person!=NULL)
{
cur=person;
node=(stud*)malloc(sizeof(stud));
if(node!=NULL)
{
printf("请输入新人的姓名和年龄:\n");
scanf("%s%d",node->name,&node->age); /*为新的节点输入数据内容*/
if(1==post)
{
node->next=person->next;
person->next=node;
}
else
{
for(i=2;i<post+2;i++)
{
pre=cur;
cur=cur->next;
}
node->next=pre->next;
pre->next=node;
}
}
}
printf("\n");
return(person);
}
stud *Reverse(stud *person) /*对单链表进行逆序操作的函数*/
{
stud *cur,*tmp; //cur将代表逆序后单链表的第一个节点
//tmp代表原单链表中cur之后紧邻的节点,起交换作用
if(person!=NULL)
{
cur=person->next;
person->next=NULL; /*将原单链表置空*/
while(cur!=NULL) /*如果cur不为NULL*/
{
tmp=cur->next; /*把当前节点的下一个节点赋给tmp */
cur->next=person->next; //若当前节点为原链表中的第一个节点,则使其next指向NULL
//否则使其next指向原链表中当前节点的上一个节点,也就是正在逆序中的第一个节点
person->next=cur; /*使头指针指向当前节点*/
cur=tmp; /*把原cur的下一个节点赋给cur*/
}
}
return(person);
}
void GetMid(stud *person) //获取中间节点的数据
{
stud *onestep,*twostep; //采用步进的策略,一个每次步进1,另一个每次步进2,这样当步进为2的指针指向的节点的next为空时,另一个指针刚好指向中间节点或者中间的第一个节点
if(N%2) //判断以决定采用的步进策略
{
onestep=twostep=person->next;
while(twostep->next!=NULL)
{
twostep=twostep->next->next;
onestep=onestep->next;
}
printf("\n处于中间位置的人只有一个,\n\t其名称为:%s,其年龄为:%d。\n\n",onestep->name,onestep->age);
}
else
{
onestep=twostep=person;
while(twostep->next!=NULL)
{
twostep=twostep->next->next;
onestep=onestep->next;
}
printf("\n处于中间位置的人有两个,\n\t第一个名称为:%s,其年龄为:%d;\n\t第二个名称为:%s,其年龄为:%d。\n\n",onestep->name,onestep->age,onestep->next->name,onestep->next->age);
}
}
void Print(stud *person)
{
int post=1;
stud *cur;
cur=person->next;
printf("当前的节点信息如下所示:\n");
while(cur!=NULL)
{
printf("第%d个人的姓名是:%s,年龄为:%d;\n",post,cur->name,cur->age);
cur=cur->next;
post++;
}
N=--post;
printf("当前单链表的长度是:%d。\n\n",N);
}
int main()
{
int number,post,i;
stud *head;
head=Create(N);
Print(head);
for(i=0;i<times;i++)
{
GetMid(head);
printf("请输入要删除的节点的位置:\n");
scanf("%d",&number);
Delete(head,number);
Print(head);
printf("请输入要插入节点的位置(此位置是指预期插入成功后新节点在单链表中的位置):\n");
scanf("%d",&post);
Insert(head,post);
Print(head);
printf("以下展示了两次单链表的逆序!!!\n\n");
Print(Reverse(head));
Print(Reverse(head));
printf("\n注意:剩余输入轮数为:%d !!!!!\n\n",(times-(i+1)));
}
return 0;
}
调试环境:Ubuntu Desktop 8.04.4 VI 7.1.138 GCC 4.2.4
QQ:81064483
E-mail:AllenNewOK@126.com
复习之用,不足之处,敬请指正。< ^_^ >
本文介绍了一个C语言实现的单链表基本操作,包括创建、计数打印、删除节点、增加节点、逆序及查找中间节点等功能,并提供了完整的代码示例。

被折叠的 条评论
为什么被折叠?



