一.结构体的不同写法
1.结构体的定义
struct 结构体类型名 结构体变量列表;
结构体四种写法
1. struct stu{
......};//保留结构体类型名
2. struct {
.....}stu[10];//省略结构体类型名
3. typedef struct stu{
.......}STU;
stu s[10];
STU s[10];//即使重命名后也可以用原来的名字定义
4. typedef struct {
.......}STU;
STU s[10];
2.通过以下方式访问结构体中的数据
- 普通类
结构体变量名 . 成员名
- 指针类
(*结构体指针变量名). 成员名 (点的运算优先级高于星号)
结构体指针变量名 -> 成员名
二.链表简介
一.链表中结点的定义
struct stu_node{
char num[10];
char name[10];
int c;//以上为数据域
struct stu_node *next;//指向下一个结点的指针(指针域)
};
struct stu_node *head, *newN, *tail;
*head 为头指针指向链表的第一个结点
*newN用来指向新建结点,他既可以操作数据域也可以操作指针域
*tail用来指向链表的尾结点
结点 = 数据域 + 指针域
二.创建学生链表
1.开辟一个新结点
newN = (struct_node *)malloc(sizeof(struct_node));
strcpy(newN -> num, num);
newN -> score = score;//先用newN指针指向变量给数据域中的变量赋值
newN -> next = NULL;
//再用newN指针操作指针域的next指针,由于现在只有一个结点所以定义三个指针都指向他,由于tail指针也指向它所以把next指针置为空
2.将新结点连接到表位
(1)对于空表即新结点是链表的第一个结点
head = newN;
将头指针指向新结点
(2)对于非空表,将新结点链接到尾结点之后
tail->next = newN;
让尾指针找到并指向next后让next指向新结点
(3)将链表尾指针指向新结点
tail->newN;
3.一个标准范例
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu_node{
char num[10];
int score;
struct stu_node *next;
};
struct stu_node *stu_create()
{
struct stu_node *head, *newN, *tail;
char num[10];
int score;
//创建第一个结点并输入数据
scanf("%s%d", num, &score);
newN = (struct_node *)malloc(sizeof(struct_node));
strcpy(newN -> num, num);
newN -> score = score;
newN -> next = NULL;
head = newN;
tail = newN;
//继续创建后续结点
while(1){
scanf("%s", num);
if(strcmp(num, "0") == 0) break;
else {
scanf("%d", &score);
newN = (struct_node *)malloc(sizeof(struct_node));
newN -> score = score;
newN -> next = NULL;//新结点使next指针暂时置空
tail -> next = newN;//前一个结点的尾指针使next指针指向新结点
tail = newN;//尾指针指向新结点
}
}
return head;
}
PS:此处新建结点最常见的错误就是写成指针++,但是请注意结点在内存中所占的储存空间并不一定连续,所以不能用这种方式来移动指针
三.链表对数据的输出,修改,删除
1.输出
void stu_print(struct stu_node *head)
{
struct stu_node *p = head;
if(p == NULL)//这就是为啥尾结点的next指针置空的原因
{
printf("学生信息为空!");
return;
}
printf("学号\t分数\n");
while( p != NULL)
{
printf("%s%d", p -> num, p -> score);
p = p -> next;//p指向下一个结点
}
}
2.修改
void stu_modify(struct stu_node *head)
{
char num[10];
struct stu_node *p = head;
if(head == NULL)
{
printf("学生信息为空!");
return;
}
printf("请输入要修改学生的学号:");
scanf("%s", num);
while(strcmp(p -> num, num) != 0 && p != NULL)
p = p -> next;
if(p != NULL)
{
printf("请输入要修改学生的分数:");
scanf("%d", &p -> score);
}
else printf("未找到该学号学生!");
}
3.删除

struct_node *stu_delete(struct stu_node *head)
{
char num[15];
struct stu_node *p = head, *q;
if(p == NULL)
{
printf("学生信息为空!");
return;
}
printf("请输入要删除学生的学号:");
scanf("%s", num);
while(strcmp(p -> num, num) != 0 && p != NULL)
{
q = p;
p = p -> next;
}
if(p != NULL)
{
if(p == head) head = p -> next;//头指针指向待删结点的下一个结点
else q -> next = p -> next;//前一个指针结点指向待删结点的下一个结点
free(p);//释放待删除结点所占内存空间
}
else printf("未找到该学号的学生");
return head;
}
四.应用举例 :教职工系统
编写教职工系统
编写程序,在主函数中调用create函数创建链表,调用findmax函数找到年龄最大的职工,del函数删除一个职工(要删除的职工编号在主函数中输入,并存放在number字符数组中)。
员工结构体的定义如下:
typedef struct wrk_node
{
char num[15];
int age;
struct wrk_node * next;
}WORKER;
//建立链表函数,返回头指针,当职工号为0时结束输入
WORKER * create( )
{
}
//查找年龄最大的职工,并返回指针
WORKER * findmax(WORKER *head)
{
}
//删除职工,number中为删除的职工号,返回头指针
WORKER * del( WORKER *head ,char number[ ])
{
}
程序如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct wrk_node
{
char num[15];
int age;
struct wrk_node *next;
}WORKER;
WORKER * create();
WORKER * findmax(WORKER *head);
WORKER * del( WORKER *head ,char number[ ]);
void print(WORKER *head);
int main()
{
WORKER *head = NULL, *max;
printf("----------------------------------------------\n");
printf("Welcome To The Administration Of The Staffs!\n");
printf("1.New\n");
printf("2.Age Findmax\n");
printf("3.Del\n");
printf("4.Print\n");
printf("----------------------------------------------\n");
int choice;
while(1)
{
printf("Please choose a number(1-4)\n");
scanf("%d", &choice);
switch(choice)
{
case 1:head = create();break;
case 2:max = findmax(head);
printf("年龄最大的职工的工号为%s\n", max -> num);
printf("其年龄是%d岁\n", max -> age);
break;
case 3:char number[15];
printf("请输入要删除职工的工号:");
scanf("%s", number);
head = del(head, number);break;
case 4:print(head);break;
default:exit(0);
}
}
return 0;
}
//建立链表函数,返回头指针,当职工号为0时结束输入
WORKER *create()
{
WORKER *head, *newN, *tail;
char num[15];
newN = (WORKER*)malloc(sizeof(WORKER));
printf("请输入职工的工号和年龄:");
scanf("%s%d", newN -> num, &newN -> age);
newN -> next = NULL;
head = newN;
tail = newN;
while(1)
{
printf("请输入职工的工号和年龄:");
scanf("%s", num);
if(strcmp(num, "0") == 0) break;
else{
newN = (WORKER*)malloc(sizeof(WORKER));
strcpy(newN -> num, num);
scanf("%d", &newN -> age);
newN -> next = NULL;
tail -> next = newN;
tail = newN;
}
}
return head;
}
//查找年龄最大的职工,并返回指针
WORKER * findmax(WORKER *head)
{
WORKER *p = head, *max = head;
while(p != NULL)
{
if(p -> age > max -> age) max = p;
p = p -> next;
}
return max;
}
//删除职工,number中为删除的职工号,返回头指针
WORKER *del(WORKER *head, char number[ ])
{
WORKER *p = head, *q;
while((strcmp(p -> num, number) != 0) && (p != NULL))
{
q = p;
p = p -> next;
}
if(p != NULL)
{
if(p == head) head = p -> next;
else q -> next = p -> next;
free(p);
}
return head;
}
//输出
void print(WORKER *head)
{
WORKER *p = head;
printf("工号\t年龄\n");
while(p != NULL)
{
printf("%s\t%d\n", p -> num, p ->age);
p = p -> next;
}
}