C语言用typedef定义一个单向链表的节点的数据结构,请大侠看看我这种方式错在哪里?如何修改?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言用typedef定义一个单向链表的节点的数据结构,请大侠看看我这种方式错在哪里?如何修改?相关的知识,希望对你有一定的参考价值。

#include<stdio.h>
#include<stdlib.h>

typedef struct STU
long num;
float score;
struct STU *next;
stu;

int n;

stu *creat(void) //创建单向链表 error C2275: 'stu' : illegal use of this type as an expression

n =0;
stu *p1;
stu *p2;
stu *head;
p1 = p2 = (stu *)malloc(sizeof(stu));
head = NULL;

scanf( "%ld,%5.1f",&p1->num,&p1->score );
while( p1->num != 0 )

n = n+1;

if( n = 1 )
head = p1;
else
p2->next =p1;
p2 = p1;
p1 = (stu *)malloc(sizeof(stu));
scanf( "%ld,%5.1f",&p1->num,&p1->score );

p2 ->next = NULL;
return head;

参考技术A #include "stdlib.h"
#include "stdio.h"

//链表的类型定义
typedef struct node

 int data;    //值域
 struct node *link; //指针域                                                   
*PNode,*LinkList;
//typedef struct node *PNode;
//typedef struct node *LinkList;

//创建空链表
LinkList createNullist_link(void)

 LinkList list=(LinkList)malloc(sizeof(struct node));//申请表头结点空间
 if(list!=NULL) list->link=NULL;
 else printf("Out of space!\\n");//创建失败
 return(list);


//判断空链表
int isNullist_linkq(LinkList list)

 return(list->link==NULL);


//在单链表中求某元素的存储位置
PNode locate_link(LinkList list,int x)
//在list 带有头结点的单链表中找第一个值为x的结点存储位置
 PNode p;
 if(list->link==NULL)  return(NULL);
 p=list->link;
 while(p!=NULL && p->data!=x) p=p->link;
 return(p);


// 单链表的插入
int  insertPost_link(LinkList list,PNode p,int x)
//在list 带有头结点的单链表中,p所指结点后面插入元素x
 PNode q=(PNode )malloc(sizeof(struct node));
 if(q==NULL)  
 
  printf("Out of space!!!\\n");
  return(0);
 
 else
 
  q->data=x;
  q->link=p->link;
  p->link=q;
  return(1);
 


// 在单链表求p所指结点的前驱结点
PNode  locatePre_link(LinkList list,PNode p)

 PNode p1;
 if(list->link==NULL)  return(NULL);
 while(p1!=NULL && p1->link!=p) p1=p1->link;
 return(p1);


// 单链表的删除
int  insertPost_link(LinkList list,int x)
//在list 带有头结点的单链表中删除第一个值为x的结点
 PNode p,q ;
 p=list;
 if(p->link==NULL)  return(0);
 while(p->link!=NULL && p->link->data!=x)
  p=p->link;//找值为x的结点的前驱结点的存储位置
 if(p->link==NULL) //没找到值为x的结点
 
  printf("Not exist!\\n");
  return(0);
 
 else
 
  q=p->link;
  p->link=q->link;
  free(q);
  return(1);
 


void main()

 int i,x;
 PNode p;
 LinkList list1;
 list1=createNullist_link();
 if(list1!=NULL)
  printf("创建空表成功!\\n");
 p=list1;
 for(i=0;i<5;i++)
 
  printf("请输入第 %d 个结点的值:",i+1);
  scanf("%d",&x);
        insertPost_link(list1,p,x);
  p=p->link;
 
 printf("\\n"); 
 p=list1->link;
 while(p!=NULL)
 
  if(p->link==NULL)
   printf("%d",p->data);
  else
   printf("%d->",p->data);
  p=p->link;
 
 printf("\\n");
 printf("请输入删除结点的值:",i+1);
  scanf("%d",&x);
 insertPost_link(list1,x);
  printf("\\n"); 
 p=list1->link;
 while(p!=NULL)
 
  if(p->link==NULL)
   printf("%d",p->data);
  else
   printf("%d->",p->data);
  p=p->link;
 

c简单的单向链表

ps:list链表  node节点

在链表中节点就是一个个的结构体

堆空间由于在申请内存时,地址是随机的,所以要用链表的方式将其连接起来,但是链表头的地址要知道.

每个节点包含两个部分:数据区和地址区,其中指向自身类型节点的指针叫做地址域,定义结构体时别忘了随便给head附上NULL地址.(尾地址不用单独定义,因为它是在节点内的)

由于最后一个节点之后没有指向的下一个节点,所以其地址域为NULL,如果是空链表,就是只定义了一个结构体,什么数据都没有,这个时候把表头的地址初始化定为NULL

节点的插入有头插法和尾插法:

头插法就是不断地在头部位置添加节点,如上图也就是新添加的节点的地址域要指向原来的头地址,新的头地址要改为新插入的节点的地址.这样刚好在添加第一个节点的时候,初始化的头地址变为了第一个节点的地址域也就是NULL,也就是尾指针变为了NULL.调用链表中的数据时,要定义一个节点类型的指针,它指向要和头地址的指向相同,然后利用它调用第一个节点,在将此节点的地址域赋给它,再次利用它调用下一个节点...只到它为NULL指针为止.

#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node* pNext;
};
struct Node* pHead = NULL;
void AddHead(int data)
{
struct Node* p = (struct Node*)malloc(sizeof(struct Node));
p->data = data;
p->pNext = pHead;
pHead = p;
}
void Print()
{
struct Node* ptemp = pHead;
while (ptemp != NULL)
{
printf("%d ", ptemp->data);
ptemp = ptemp->pNext;
}
}
void main()
{
AddHead(1);
AddHead(2);
AddHead(3);
Print();
}

尾插法:尾插法相对来说比较麻烦,多了一个判断是不是第一个节点的过程

#include<stdio.h>
#include<stdlib.h>
struct Node
{
	int data;
	struct Node* pNext;
};
struct Node* pHead = NULL;
void AddHead(int data)
{
	struct Node* p = (struct Node*)malloc(sizeof(struct Node));
	p->data = data;
	p->pNext = pHead;
	pHead = p;
}
void AddTail(int data)
{
	struct Node* p = (struct Node*)malloc(sizeof(struct Node));
	p->data = data;
	if (pHead == NULL)
		pHead = p;
	else
	{
		struct Node* ptemp = pHead;
		while (ptemp->pNext != NULL)
		{
			ptemp = ptemp->pNext;
		}
		ptemp->pNext = p;
	}
	p->pNext = NULL;
}
void Print()
{
	struct Node* ptemp = pHead;
	while (ptemp != NULL)
	{
		printf("%d ", ptemp->data);
		ptemp = ptemp->pNext;
	}
}
void main()
{
	AddTail(1);
	AddTail(2);
	Print();
}

链表中删除节点(数据结构中删除是最麻烦的)

按照上图的方法,中间和尾部的节点删除都可以成功,但是可以发现在删除头部第一个节点后打印会出错,是因为head前面没有节点了,头地址还没被改变,所以要在循环寻找数据之前,写一个if语句专门针对一下删除第一个节点的情况。还可以发现在整个链表为空的时候删除也会出错,所以也进行了特殊处理.所以在一个功能中要测试头,中间,尾和空四个特殊位置

#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node* pNext;
};
struct Node* pHead = NULL;
void AddHead(int data)
{
struct Node* p = (struct Node*)malloc(sizeof(struct Node));
p->data = data;
p->pNext = pHead;
pHead = p;
}
void AddTail(int data)
{
struct Node* p = (struct Node*)malloc(sizeof(struct Node));
p->data = data;
if (pHead == NULL)
pHead = p;
else
{
struct Node* ptemp = pHead;
while (ptemp->pNext != NULL)
{
ptemp = ptemp->pNext;
}
ptemp->pNext = p;
}
p->pNext = NULL;
}
void Print()
{
struct Node* ptemp = pHead;
while (ptemp != NULL)
{
printf("%d ", ptemp->data);
ptemp = ptemp->pNext;
}
printf("\\n");
}
void modify(int data, int newdata)
{
struct Node* ptemp = pHead;
if (ptemp == NULL)
{
puts("fail");
return;
}
while (ptemp->data != data&&ptemp != NULL)
{
ptemp = ptemp->pNext;
}
if (ptemp->data == data)
ptemp->data = newdata;
if (ptemp == NULL)
puts("fail");
}
int Delete(int data)
{
struct Node* ptemp = pHead;
struct Node* pfront = pHead;
if (ptemp == NULL)
{
puts("fail");
return 0;
}
if (ptemp->data == data)
{
pHead = ptemp->pNext;
free(ptemp);
ptemp = NULL;
return 1;
}
while (ptemp != NULL)
{
if (ptemp->data == data)
{
pfront->pNext = ptemp->pNext;
free(ptemp);
ptemp = NULL;
return 1;
}
pfront = ptemp;
ptemp = ptemp->pNext;
}
return 0;
}
void main()
{
modify(1,2);
Delete(1);
AddTail(1);
AddTail(2);
AddTail(4);
AddHead(3);
Print();
Delete(3);
Print();
modify(4, 5);
modify(1, 6);
Print();
}

  

 

以上是关于C语言用typedef定义一个单向链表的节点的数据结构,请大侠看看我这种方式错在哪里?如何修改?的主要内容,如果未能解决你的问题,请参考以下文章

用C语言写一个链表储存学生信息

[ 数据结构--C语言 ] 无头单向非循环链表的简单实现(单链表)

用Java语言实现单向链表

[数据结构]双向链表(C语言)

C语言的链表怎么排序

C语言一篇文章带你彻底了解单向链表的增删查改