当前位置:首页 » 编程语言 » c语言动态链表教程
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言动态链表教程

发布时间: 2023-03-07 21:42:47

c语言 建立一个链表,实现增删改查

下面是以前写的一个关于链表的综合操作,你可以看看,应该可以满足你的要求。
/********************************************************************
created: 2009/09/15
created: 16:9:2009 17:20
filename: E:\dd\lianbiao\lianbiao.cpp
author:
purpose: 一个win32 的控制台程序
实现单项链表的数据删除、插入、排序等功能
*********************************************************************/
#include <stdio.h>
#include "windows.h"
#include "malloc.h"

#define LEN sizeof(struct student)
#define NULL 0
#define N 5 //N为所要创建的链表的长度

int n = 0; //定义全局变量n,表示链表的节点个数
/*******************************************************************
Author/data: /2009/09/15
Description: 声明一个结构体作为链表的节点.
tip: student 只是一个标签,是不能声明变量的
*********************************************************************/
struct student
{
int num;
float cj;
struct student *Pnext;
};

/*******************************************************************
Author/data: /2009/09/15
Description: 创建一个动态链表
参数: 返回链表的第一个节点的地址
x 为链表的长度
*********************************************************************/
struct student *pa(int x)
{
struct student *head;
struct student *p1,*p2;

// n = 0;
p1 = p2 = (struct student *)malloc(LEN); //开辟一个结构体内存
fflush(stdin); // 清除缓冲区数据 避免直接读入缓冲区数据
scanf("%d,%f",&p1->num,&p1->cj);
head = NULL;
while(p1->Pnext != NULL)
{
n = n+1;
if(n == 1)
{
head = p1; // 链表的头地址
}
else
{
p2->Pnext = p1; //链接链表数据
}
/* 判断是否最后一个 */
if(n >= x)
{
p1->Pnext = NULL;
}
else
{
p2 = p1;
p1 = (struct student *)malloc(LEN);
fflush(stdin);
scanf("%d,%f",&p1->num,&p1->cj);
}
}
return(head);
}
/*******************************************************************
Author/data: /2009/09/15
Description: 输出一个链表
参数: head为第一个节点的地址
*********************************************************************/
void print(struct student *head)
{
struct student *p;

int i = 0;
printf("\nNow,These %d records are:\n",n);
p = head;
if(head != NULL) // 如果链表不是空的,则进行数据输出
{
do
{
printf("%d\t",i++);
printf("%5d %5.1f\n",p->num,p->cj); // 输出链表数据
p = p->Pnext;
}while(p != NULL);
}
}
/*******************************************************************
Author/data: /2009/09/16
Description: 释放动态链表的地址空间
参数: 链表的头地址head
无返回值
*********************************************************************/
void freelinkspace(struct student *head)
{
struct student Ltemp;
Ltemp.Pnext = head->Pnext; // Ltemp 用来存放->next,避免空间被
// 释放后,找不到下一个结点的地址
while(head->Pnext != NULL) // 判断是否已经空间释放到最后一个
{
free(head);
head = Ltemp.Pnext;
Ltemp.Pnext = head->Pnext;
}
free(head); // 释放最后一个结点空间
}

/*******************************************************************
Author/data: /2009/09/15
Description: 删除链表链表中的一个结点
参数: head 为第一个节点的地址
num 为要删除结点的序号(head->num)
*********************************************************************/
struct student *del(struct student *head,int num)
{
struct student *p1,*p2;
p1 = head;
while(p1->num!=num && p1->Pnext!=NULL) // 寻找要删除的结点
{
p2 = p1; // p2 存放删除结点的前一个结点地址
p1 = p1->Pnext; // p1 存放要删除的结点
}
if(num == p1->num) // 是否找到要删除结点
{
if(p1 == head) // 删除的是第一个结点
{
head = p1->Pnext;
}
else if(p1->Pnext == NULL) // 删除的是最后一个结点
{
p2->Pnext = NULL;
}
else // 删除中间的结点
{
p2->Pnext = p1->Pnext;
p1->Pnext = NULL;
}
printf("delete: %d\n",num);
n = n-1; // 链表长度 - 1
}
else
{
printf("%d not been found! \n",num);
}
delete(p1);
return(head);
}
/*******************************************************************
Author/data: /2009/09/16
Description: 添加一个结点到链表中
参数: head 为第一个结点的地址指针
stud 为要插入的结点的地址指针
*********************************************************************/
struct student *insert(struct student *head,struct student *stud)
{
struct student *p0,*p1,*p2;
p0 = stud;
p1 = head;
while(p0->num>p1->num && p1->Pnext!=NULL) // 找到添加结点的位置
{
p2 = p1; // p2 存放要添加的前一个结点的地址
p1 = p1->Pnext; // p1 存放要添加的后一个结点的地址
}
if(p0->num<=p1->num && p1->Pnext!=NULL)
{
if(p1 == head) // 添加结点到第一个位置
{
p0->Pnext = p1;
head = p0;
}
else
{
p2->Pnext = p0;
p0->Pnext = p1;
}
}
else // 添加结点到最后一个位置
{

p1->Pnext = p0;
p0->Pnext = NULL;
}
n = n+1; // 结点数目 + 1
return(head);
}
/*******************************************************************
Author/data: /2009/09/16
Description: 链表的重新排序===按照.num(不能重复)的大小从小到大排
列链表数据
参数: head 接收链表第一个节点的地址指针
返回值为新生成链表的第一个节点的地址指针
*********************************************************************/
struct student *linkpaix(struct student *head)
{
struct student *stemp,*ltemp,*shead,*head_h; /* */
struct student *p,*q; /* 申请两个链表指针,用来储存链表交换过
程的中间值 */
head_h = head;
ltemp = head;

p = (struct student *) malloc(LEN);
q = (struct student *) malloc(LEN); /* 为p,q开辟动态存储空间 */

/* -==== 先将链表的第一个数据与其他数据比较 ====- */
while(head->Pnext != NULL)
{
shead = head;
head = head->Pnext;
if(ltemp->num > head->num)
{
if(ltemp == shead)
{
ltemp ->Pnext = head ->Pnext;
head ->Pnext = ltemp;
}
else
{
p->Pnext = head ->Pnext;
q->Pnext = ltemp ->Pnext;
head ->Pnext = q->Pnext;
shead ->Pnext = ltemp;
ltemp ->Pnext = p->Pnext;
}
head_h = head;
head = ltemp;
ltemp = head_h;
}

}
/* -==== 先将链表的第一个数据与其他数据比较 ====- */

/* -==== 比较链表第一个以外的数据 ====- */
while(ltemp ->Pnext != NULL)
{
stemp = ltemp;
ltemp = ltemp ->Pnext;
head = ltemp;
while(head->Pnext != NULL)
{
shead = head;
head = head->Pnext;
if(ltemp->num > head->num)
{
if(ltemp == shead)
{
p->Pnext = head ->Pnext;
stemp ->Pnext = head;
head ->Pnext = ltemp;
ltemp ->Pnext = p->Pnext;
}
else
{
p->Pnext = head ->Pnext;
q->Pnext = ltemp ->Pnext;
stemp ->Pnext = head;
head ->Pnext = q->Pnext;
shead ->Pnext = ltemp;
ltemp ->Pnext = p->Pnext;
}
head = ltemp;
ltemp = stemp ->Pnext;
}
}

}
/* -==== 比较链表第一个以外的数据 ====- */

free(p);
free(q); // 释放p,q的动态存储空间
return(head_h);
}

/*******************************************************************
Author/data: /2009/09/15
Description: 主函数
参数:
*********************************************************************/
void main()
{
struct student *phead,*pins; // 定义2个链表指针
int delnum, selflog,flog_a = 1,Nf = 1; // 要删除的对象id
char delflog ; // 删除标志y/n
char insflog, flog_nx = 'n';
char flog_free ; // 释放标志
/* === 输入N个数据 === N 为定值
printf("please input %d numbers:\n",N);
phead = pa(N); // 创建一个动态链表,并赋值
print(phead); // 输出链表数据
*/

/* === 输入Nx个数据 === Nx 为输入值 === */
int Nx; // Nx 想要输入的链表长度
printf("How long do you want establish? \t");
fflush(stdin);
scanf("%d",&Nx);
/* -== 判断创建的是否是一个空链表 ==- */
while(Nx == 0)
{
printf("您要创建的是一个空链表,是否确定?y/n \t");
fflush(stdin);
scanf("%c",&flog_nx);
if(flog_nx == 'n')
{
printf("How long do you want input?\t");
fflush(stdin);
scanf("%d",&Nx);
}
else if(flog_nx == 'y') goto endl;
else
{
printf("wrong input!\n");
printf("How long do you want input?\t");
fflush(stdin);
scanf("%d",&Nx);
}
}

printf("please input %d numbers: ",Nx);
printf("如:1,3 两个数中间以,隔开\n");
phead = pa(Nx); // 创建一个动态链表,并赋值
print(phead); // 输出链表数据

/* -== 链表操作 ==- */
while(flog_a)
{
if(phead == NULL) {printf("链表已空,无法操作\n"); flog_a = 0; break;}
printf("\n操作\n1:\t插入数据\n2:\t删除数据\n3:\t排序\n4:\t清屏\n5:\t输出现在的链表数据\n0:\texit\n");
printf("\nPlease input:\t");
fflush(stdin);
if(scanf("%d",&selflog)) // select flog 选择项
switch(selflog)
{
case 1 :
/* ====== 插入数据到链表 ====== */
printf("insert someone? y/n\t");
fflush(stdin);
scanf("%c",&insflog);
while(insflog != 'n')
{
while(insflog != 'y'&& insflog != 'n')
{
printf("wrnong input,please input again. \n");
printf("another one? y/n\t");
fflush(stdin);
scanf("%c",&insflog);
}
printf("please input the date:\n");
pins = (struct student *)malloc(LEN);
fflush(stdin);
scanf("%d,%f",&pins->num,&pins->cj);
phead = insert(phead,pins);
print(phead);

printf("another one? y/n\t");
fflush(stdin);
scanf("%c",&insflog);
while(insflog != 'y'&& insflog != 'n')
{
printf("wrnong input,please input again. \n");
printf("another one? y/n\t");
fflush(stdin);
scanf("%c",&insflog);
}
}
/* ====== 插入数据到链表 ====== */
break;

case 2 :
/* ====== 删除链表中的数据 ====== */
printf("del someone? y/n\t");
fflush(stdin);
scanf("%c",&delflog);
while(delflog != 'n' && phead != NULL)
{
while(delflog != 'y'&& delflog != 'n')
{
printf("wrnong input,please input again. \n");
printf("del someone? y/n\t");
fflush(stdin);
scanf("%c",&delflog);
}
printf("please input the student what you want del:\n");
fflush(stdin);
scanf("%d",&delnum);
phead = del(phead,delnum);
print(phead);

printf("another one? y/n\t");
fflush(stdin);
scanf("%c",&delflog);
if((n+1)==0)
{
printf("There is no more num could be del!\n");
break;
}
}
/* ====== 删除链表中的数据 ====== */
break;

case 3 :
/* ====== 排列链表数据 ====== */
printf("\n排序之后:");
phead = linkpaix(phead);
print(phead); // 排序该数据链表
/* ====== 排列链表数据 ====== */
break;
case 4 :// clrscr();
system("cls");
break;

case 5 : print(phead); break;
case 0 : flog_a = 0 ; break; /* 退出 */

default : printf("wrong input\nPlease input again");
break;
}
else printf("非法输入!\n");
}
endl: while(1)
{
if(Nx == 0)
{
printf("Can't establish the link!\n");
break;
}
printf("\n保留数据?y/n\t"); // 是否释放地址空间
fflush(stdin);
scanf("%c",&flog_free);
if(flog_free == 'y')
{
break;
}
else if(flog_free == 'n')
{
freelinkspace(phead);
break;
}
else
{
printf("wrong input!\n");
}
}

printf("OVER!\nGOOD LUCK!\n");
}

⑵ C语言链表的建立与插入

#include
<stdio.h>
#include
<stdlib.h>
//使用结构体构建链表
struct
node{
int
data;
struct
node
*next;
};
void
main()
{
int
a,n=1;
struct
node
*p,*head,*t;
head=(struct
node
*)malloc(sizeof(struct
node));
//p=(struct
node
*)malloc(sizeof(struct
node));
//申请动态空间
p=head;
//申请动态空间
t=(struct
node
*)malloc(sizeof(struct
node));
for(;n<=5;n++)
//输入1,3,5,7,9
{
p->data=2*n-1;
p->next=(struct
node
*)malloc(sizeof(struct
node));
p=p->next;
}
printf("原始链表如下:\n");
//输出原始链表
for(p=head;p->next!=NULL;p=p->next)
{
printf("%d
",p->data);
}
printf("\n请输入需要插入的数据\n");
//输入所要插入的新数据
scanf("%d",&a
);
for(p=head;p->next!=NULL;)
//按顺序插入相应位置
{
if(p->data
<=
a
&&
(p->next)->data
>=
a)
{
t->data
=a;
t->next
=p->next
;
p->next=t;
break;
}
p=p->next
;
}
printf("插入新数据后的链表\n");
//输出插入新数据的链表
for(p=head;p->next!=NULL;)
{
printf("%d
",p->data);
p=p->next;
}
printf("\n");
free(p);
free(head);
free(t);
}

⑶ c语言链表,非常感谢

//WIN-TC是什么turbo? 我在DEV-C下改的,应该也没问题吧
#include<stdio.h>
#include<malloc.h>
//#define NULL 0 //不用重定义NULL把,空指针用NULL就可以
struct student
{
int num;
char name[20];
float score;
struct student *next;
};
int n=0;
/*建立动态链表*/

/* 这个函数,有重要的问题,你在函数里创建了临时类,st,head指向它,但是当这个函数结束时,这个类会被销毁,head将是个没有指向的指针,所以当在函数中返回类时,需要堆分配内存
*/
struct student *creat(void)
{
struct student *p1=NULL,*head=NULL; // 这里一个学生类指针即可
struct student *st = (struct student *)malloc(sizeof(struct student)); //同上解释
printf("Please input records:\n");
scanf("%d%s%f",&(st->num),st->name,&(st->score));
p1=st;
p1->next = NULL;
if(st->num!=0)
head=p1;
while(p1->num!=0)
/*这个链表的创立,无非就是那些步骤,你必然明白,再不行,画个示意图就明白了,注意的是,什么时候指针赋值,什么时候用指针控制变量
*/
{n=n+1;
printf("%dEnd\n",n);

p1->next = (struct student *)malloc(sizeof(struct student));
//这句话至少得有一个“->”,需要控制变量

p1->next->next = NULL;
scanf("%d%s%f",&(p1->next->num),p1->next->name,&(p1->next->score));
if(n!=1)
{
p1 = p1->next;

}
}

printf("\nOver.\n");
/*printf("%o\n",head);
if(head!=NULL)
printf("%10d%10s%10.1f\n",head->num,head->name,head->score);*/
return(head);
}
/*输出*/
void print(struct student *head)
{
struct student *p;
p=head;
/*printf("%o\n",head);*/
getch();
//if(head==NULL)
//printf("\nList null!\n");
//else
printf("\nNow,there are %d records:\n",n);
while(p!=NULL)
{
printf("%10d%10s%10.1f\n",p->num,p->name,p->score);
p=p->next;
}
}
int main()
{
struct student *head;
head=creat();
/*printf("%o\n",head);
if(head!=NULL)
printf("%10d%10s%10.1f\n",head->num,head->name,head->score);*/
print(head);
getch();

return 0;
}

/*还有些小问题,如应该创建个销毁链表函数,使堆中内存被释放,等
但不影响达到效果,做个示意够了
*/

⑷ c语言建立动态链表,我刚学编的程序,请高人帮忙指出毛病

1. 第一个for循环结构中
scanf("%d,%s",p2->num,p2->name);
改为 scanf("%d,%s",&(p2->num),p2->name);

p1=p2->next;
改为 p2->next=p1;

2.第二个for循环结构中
struct stu *p;
p=head; 每一次循环指针p都指向head
应该把他定义到for外面,赋值为head

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define NULL 0
void main()
{
struct stu
{int num;
char name[10];
struct stu *next;
};

struct stu *head,*p1,*p2,*p;
int n;
p1=(struct stu*)malloc(sizeof(struct stu));
head=p1;
for(n=0;n<=3;n++)
{p2=p1;
printf("input:");
scanf("%d,%s",&(p2->num),p2->name);
p1=(struct stu*)malloc(sizeof(struct stu));
p2->next=p1;
}
p1->next=NULL;

p=head;

for(n=0;n<=3;n++)
{
printf("%d,%s\n",p->num,p->name);
p=p->next;
}
getch();
}

后面这个for结构可以改为
do
{
printf("%d,%s\n",p->num,p->name);
p=p->next;
}while(p->next!=NULL);

⑸ C语言如何用动态链表储存数据

单链表,双链表,堆 都可以,不过看您要存储什么数据 以单链表为例: 定义一个节点结构 typedef struct LNode{ ElementType date; struct Lnode *next; }Lnode; 然后用malloc开辟需要的节点空间,把数据存进去就可以了 p = (Lnode) malloc (sizeof(Lnode)); //开辟一个节点,p为所开辟空间的指针 至于查找,从头节点开始q = p->next ;一个个查就行了。