定义链表的结构形式:

动态链表_链表删除

链表中的每个元素称为结点,结点包含数据域和指针域。

动态链表_结点_02

写一个链表:

先介绍下关于内存空间分配函数malloc

调用形式:(类型说明符*)malloc(size)

功能:在内存的动态存储区分配一块长度为size个字节的连续区域。函数的返回值为该区域的首地址。

说明:(类型说明符*)表示把返回值强制转换为该类型指针,"size“用于指定空间大小,如果空间分配失败,无足够空间可以分配,则函数返回NULL。

还有一个calloc函数

调用形式:(类型说明符*)calloc(n,size)

功能:在内存动态存储区中分配n块长度为”size"字节的连续区域。函数的返回值为该区域的首地址,如果空间分配失败,返回NULL。

释放内存空间函数free

调用形式:void free(指针变量p)

功能:释放p所指向的一块内存空间,p是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区域应是由malloc,calloc函数所分配的区域。

例:

struct node*p=(struct node*)malloc(sizeof(struct node))

动态创建一个结点,这个结点的首地址存储在指针变量p中。

1.动态建立链表:

动态链表_链表插入_03

尾结点没有后续结点,所以一般将其指针域设置为NULL,表示链表操作的结束条件

2.把链表中数据打印出来:

动态链表_插入和删除结合_04

插入:

1为顺序建表,逆序建表如下:

动态链表_结点_05

3.步骤1和2结合:

动态链表_插入和删除结合_06


下面进入链表的插入:

在新节点的表头结点插入:

p->next=head; head=p;(当head为空时,插入的p为第一个结点)

将新节点在表尾结点之后进行插入:

动态链表_链表_07

总结:先找到表尾结点,然后直接用表尾的指针指向插入p,p为新的尾结点

在指定位置进行插入:

动态链表_插入和删除结合_08

总结:指定位置插入结点,先找一个条件进行移动,然后根据判断进行将p插入

删除某个结点:

1.删除表头结点:

q=head; head=head->next; free(q); --free(q)表示释放q的空间

2.删除尾巴结点:

动态链表_结点_09

总结:先找到尾巴结点,然后把跟在后面的q2指向空,表示链表结束,释放q1。

3.删除指定位置结点:

动态链表_结点_10

总结:先找一个判断条件进行移动,然后判断将某个结点进行删除。




练习:先建立一个学生信息表,该表按学生成绩进行降序排序,将新同学的信息插入到表中,保持表中有序,并且删除指定学号学生信息。


#include<stdio.h>

#include<string.h>

#include<malloc.h>

struct student

{

int num;

char name[20];

float score;

struct student* next;

};

//建立链表

struct student* fun(int n) //建立n个结点

{

struct student* head, * p, * q;

head = NULL;

q = NULL;

int i;

for (i = 0; i < n; i++)

{

p = (struct student*)malloc(sizeof(struct student));

printf("输入学号,分数:");

scanf("%d,%f",& p->num, &p->score);

rewind(stdin);

printf("输入姓名:");

gets(p->name);

p->next = NULL;

if (head == NULL)

{

head = p;

q = p;

}

else

{

q->next = p;

q = p;

}

}

return head;

}

// 遍历链表

void func(struct student* head)

{

struct student* p;

p = head;

while (p != NULL)

{

printf("输出学号,姓名,分数:%d,%s,%.2f\n", p->num, p->name, p->score);

p = p->next;

}

}

//结点插入

struct student* fun1(struct student* head, struct student* p)

{

struct student* q1, * q2;

q1 = head;

q2 = NULL;

while (q1 != NULL && q1->score >= p->score)

{

q2 = q1;

q1 = q1->next;

}

if (q2 == NULL) //表头插入

{

p->next = q1;

head = p;

}

else if (q1 == NULL) //表尾插入

q2->next = p;

else //在q1结点前,q2后插入

{

p->next = q1;

q2->next = p;

}

return head;

}

//结点删除

struct student* fun2(struct student* head, int num)

{

struct student* q1, * q2;

q1 = head;

q2 = NULL;

while (q1 != NULL && q1->num != num)

{

q2 = q1;

q1 = q1->next;

}

if (q2 == NULL)

head = q1->next;

else if (q1 != NULL)

q2->next = q1->next;

free(q1);

return head;

}

int main()

{

struct student* p, * p1, * p2 ,*p3,* q;

q = (struct student*)malloc(sizeof(struct student));

q->num = 103;

printf("输入这个同学的姓名:");

gets(q->name);

q->score = 85;

q->next = NULL;

printf("输入你要输入信息的个数:");

int n=0,n1=0;

scanf("%d", &n);

p = fun(n);

func(p);

printf("打印插入后链表:\n");

p1 = fun1(p,q); //结点插入

func(p1);

printf("输入你要删除同学信息的学号:");

scanf("%d", &n1);

printf("打印删除后链表:\n");

p2 = fun2(p,n1); //删除学号为n1的同学的信息

func(p2);

printf("打印插入后删除的链表:\n");

p3 = fun2(p1, n1);
func(p3);

return 0;

}


如有不对,欢迎指正。