目录
十三、链表
13.1动态内存申请
13.2结构体指针
13.3链表
13.3.1链表:
13.3.2链表分类:
13.3.3链表操作:
十三、链表
13.1动态内存申请
动态内存申请的空间 在 堆区 , 特点:人为申请,人为释放。
malloc--- 分配空间
#include <stdlib.h>
malloc函数申请一个大小为size字节的空间,如果申请失败返回NULL,如果申请成员返回申请空间首字节的编号。
例子:
在堆区 申请一个int型空间的大小。
int * p = (int *)malloc(sizeof(int));
然后操作int空间赋值为10;
*p = 10;
printf("%d \n",*p);
例子:
在堆区 申请 4个char型的空间大小
char *q = (char *)malloc(sizeof(char) * 4);
*(q+0) = 'a';
*(q+1) = 'b';
*(q+2) = 'c';
*(q+3) = '\0';
printf("%s",q);
例子:
typedef struct book
{
char bookName[30];
char author[20];
char bookNum[10];
int hot;
int kc;
float price;
}BK_t;
练习:
strcut Data
{
int m;
int* p;
};
strcut Data d1;
d1.m = 10;
d1.p = (int*)malloc (sizeof (int));
*(d1.p) = 30;
struct Data d2;
d2 = d1;
d2.m = 100;
*(d2.p) = 50;
d1.m = __10_____ * (d1.p) = ____50____
d2.m = ___100____ * (d2.p) = ___50_____
13.2结构体指针
指针名->成员名
struct student
{
int sno;
char name[20];
struct student* next;
};
// struct student 成员:
// sno name next
// int char [20] struct student *
// 整型数据 字符串 保存结构体struct student空间的地址
// 申请一块结构体的空间
// 存储信息 学号 姓名 NULL
struct student* h = (struct student*)malloc (sizeof (struct student));
h->sno = 1;
strcpy (h->name, "小明");
h->next = NULL;
// 申请一块结构体的空间
// 存储信息 学号 姓名 NULL
struct student* p = (struct student*)malloc (sizeof (struct student));
p->sno = 2;
strcpy (p->name, "小黄");
p->next = NULL;
// 将第一个结构体里面的next指针 指向 第二个结构体。
h->next = p;
printf ("%d %s\n", h->sno, h->name);
printf ("%d %s\n", h->next->sno, h->next->name);
13.3链表
数据结构,用的时候开空间,用完之后释放。
链表存储数据的时候,开空间就可以使用动态内存申请。
13.3.1链表:
存储数据的空间叫节点。
节点是结构体类型,由 数据域 和 指针域 组成。
struct xx
{
数据-- - 数据域
指针 存储下一个数据的地址 -- - 指针域
};
13.3.2链表分类:
单链表 | 单向,从前往后访问链表 |
双链表 | 双向 从前往后也可以从后往前 访问链表 |
循环链表 | 环形链表 |
有头链表 | 第一个节点不用它的数据域,只用它的指针域 |
无头链表 | 第一个节点和其他节点没有区别,都要存储数据和地址。 |
13.3.3链表操作:
以有头单向链表为例来讲。
添加节点 --- 功能
查找节点 --- 功能
删除节点 --- 功能
修改节点 --- 功能
插入节点 --- 功能
#include <stdlib.h>
#include <stdio.h>
struct Node
{
int num;
struct Node* next;
};
// head
void addNode (struct Node* head);
void allNode (struct Node* head);
void delNode (struct Node* head);
int main ()
{
// 准备工作
struct Node* head;
head = (struct Node*)malloc (sizeof (struct Node));
if (head == NULL)
{
printf ("申请内存失败");
return 0;
}
head->next = NULL;
// 添加三个节点
addNode (head);
addNode (head);
addNode (head);
// 显示所有节点
allNode (head);
delNode (head);
allNode (head);
delNode (head);
allNode (head);
delNode (head);
}
/********************************************************************
* 函数名称:addNode
* 功能描述:添加一个节点到链表末尾
* 输入参数:头指针
* 返回:void
* 其他:如果链表为空,新节点将成为头节点
*********************************************************************/
void addNode (struct Node* head)
{
// 写入节点
struct Node* add;
add = (struct Node*)malloc (sizeof (struct Node*));
if (add == NULL)
{
printf ("申请内存失败");
return 0;
}
add->next = NULL;
scanf (" %d", &add->num);
// 获取尾节点
struct Node* copy = head;
while (copy->next != NULL)
{
copy = copy->next;
}
// 链接
copy->next = add;
}
/********************************************************************
* 函数名称:allNode
* 功能描述:输出所有的节点
* 输入参数:头指针
* 返回:void
* 其他:
*********************************************************************/
void allNode (struct Node* head)
{
struct Node* copy = head->next;
while (copy != NULL)
{
printf ("%d -> ", copy->num);
copy = copy->next;
}
printf ("NULL\n");
}
/********************************************************************
* 函数名称:delNode
* 功能描述:删除节点
* 输入参数:struct Node* temp
* 返回:void
* 其他:
*********************************************************************/
void delNode (struct Node* head)
{
struct Node* copy = head;
struct Node* copynext = copy->next;
// 存储要删除的节点
int input;
scanf ("%d", &input);
//标记找不找得到
int flag = 0;
while (copy != NULL)
{
if (copynext->num == input)
{
copy->next = copynext->next;
copynext = NULL;
free (copynext);
flag = 1;
break;
}
else
{
copy = copynext;
copynext = copynext->next;
}
}
if (flag == 0)
{
printf ("没找到");
}
}