关于C语言链表的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C语言链表的相关的知识,希望对你有一定的参考价值。
/*creat a list*/
#include "stdlib.h"
#include "stdio.h"
struct list
int data;
struct list *next;
;
typedef struct list node;//这段什么意思?typedef是干什么?
typedef node *link; //这段又是什么意思?
void main()
link ptr,head;
int num,i;
ptr=(link)malloc(sizeof(node));//还有为什么每次创建链表都要有个malloc?这个有什么用?
ptr=head;
printf("please input 5 numbers==>\n");
for(i=0;i<=4;i++)
scanf("%d",&num);
ptr->data=num;
ptr->next=(link)malloc(sizeof(node));
if(i==4) ptr->next=NULL;
else ptr=ptr->next;
ptr=head;
while(ptr!=NULL)
printf("The value is ==>%d\n",ptr->data);
ptr=ptr->next;
还有那个link ptr,head什么意思?
2.其实这是一个指针定义的问题,我刚学C的时候也为之困惑,其实char *p的意思应该是char* p;把char*作为一个整体来看,p是一个字符指针类型的变量,同理因为node就是struct list,那么node*就是(struct list*)取了一个别名link,link就是和node*是同一个意思
3.malloc是系统从堆空间分配一块内存给用于,ptr指针指向这块内存空间。相对于堆空间的,有一个栈空间的概念,这个是由系统自行分配的和收回的,在函数体刚开始时由系统对变量分配空间,如int num,i;函数体结束以后由系统自动收回,而malloc分配内存空间需要用户自己用free()来释放,好像你没有写有,一般在程序结束前自己手动释放,如free(ptr);想了解的更详细一点去搜一下堆空间和栈空间的相关文章 参考技术A typedef struct list node;//定义一个自定义类型node,在这个程序中的以下部分中,node和struct list是同义词
typedef node *link; //定义一个自定义类型link,在这个程序中的以下部分中,link和node *是同义词(也就是和struct list *是同义词)
malloc()是用来分配空间标准库函数,ptr只是一个指针,系统并没有为它分配空间,所以要用malloc()函数为其分配空间,之后才可以对ptr的各个域赋值.
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");
参考技术A LZ的很好。。。
以上是关于关于C语言链表的的主要内容,如果未能解决你的问题,请参考以下文章
关于C语言链表的问题,一个排序的问题,按num排序,求大佬帮助,在线等~!有点急~!
关于c语言课程设计链表的两个问题。。(高分求助) 非常急。。。。!!。