动态链表
1.动态链表概念
动态链表就是由malloc
分配内存
2.动态链表操作接口
2.0数据结构定义
struct Student {
int num;//编号
float score;//成绩
struct Student* next;//存储下一个节点的地址
};
typedef struct Student ST;
2.1添加节点
void add(ST** phead, int inum, float iscore)//传入头节点的地址,插入数据
{
if (*phead == NULL)//判断链表是否为空
{
ST* newnode = malloc(sizeof(ST));//c99可以不强转malloc返回值
if (newnode == NULL)
{
printf("内存分配失败");
return;
}
newnode->num = inum; //节点初始化
newnode->score = iscore;
newnode->next = NULL;
*phead = newnode;//让头指针指向这个节点
}
else
{
ST* p = *phead;
while (p->next != NULL)//遍历到最后1个节点,尾部插入
{
p = p->next;
}
ST* newnode = malloc(sizeof(ST));
if (newnode == NULL)
{
printf("内存分配失败");
return;
}
newnode->num = inum; //节点初始化
newnode->score = iscore;
newnode->next = NULL;
p->next = newnode;//让头指针指向这个节点
}
}
2.2显示节点数据
void showall(ST* phead)//传入头节点,显示所有数据
{
ST* head = phead;
while (head != NULL)
{
printf("num=%d,score=%f", head->num, head->score);//访问数据
printf("%p,%p\n", head, head->next);//打印两个节点的地址
head = head->next;
}
}
2.3逆转节点
ST* rev(ST* head)//逆转
{
ST* p1, * p2, * p3;
p1 = p2 = p3 = NULL;
if (head == NULL || head->next == NULL)//为空链表或者只有1个元素
{
return head;//返回头节点
}
p1 = head;
p2 = head->next;
while (p2!=NULL)
{
p3 = p2->next;//布局三个节点
p2->next = p1;//指向前一个节点
p1 = p2;//指针向前移动,从第二个到最后一个节点
p2 = p3;
}
head->next = NULL;
head = p1;
return head;
}
2.4查找节点
ST* search(ST* head, int num)//根据编号查找节点
{
while (head != NULL)
{
if (num == head->num)
{
return head;//返回当前节点的指针地址
}
head = head->next;
}
return NULL;
}
2.5查找并修改节点数据
void change(ST* head, int oldnum, int newnum)//查找oldnum修改为newnum
{
ST* psearch = search(head, oldnum);
if (psearch == NULL)
{
printf("没找到");
}
else
{
psearch->num = newnum;
printf("修改成功");
}
}
2.6获取节点个数
int getnum(ST* head)//获取节点个数
{
int i = 0;
while (head != NULL)
{
i++;
head = head->next;
}
return i;
}
2.7删除所有节点
void *freeall(ST* head)//删除所有节点.每次删除第一个节点后面的一个节点,最后删除头节点
{
ST* p1, * p2;
p1 = p2 = NULL;
p1 = head;//头节点
while (p1->next!=NULL)//遍历所有节点
{
p2 = p1->next;//p2为p1下个节点
p1->next = p2->next;//p1存储了p2下一个节点的地址
//p1->next = p2->next;//p1存储了p2下一个节点的地址
//p2 = p1->next;//p2为p1下个节点
free(p2);
printf("\n\n\n");//访问数据,观测删除过程
showall(head);
}
free(head);
return NULL;
}
2.7删除指定节点
ST* delete(ST *head ,int num)//返回头节点,传入头节点,要删除节点的编号
{
ST* p1, * p2;
p1 = p2 = NULL;
p1 = head;//头节点
while (p1 != NULL)
{
if (p1->num == num)
{
break;
}
else
{
p2 = p1;//记录当前节点
p1 = p1->next;
}
}
if (p1 == head)
{
head = p1->next;
free(p1);
}
else
{
p2->next = p1->next;
free(p1);
}
return head;
}
2.8根据节点,头部插入
ST* HeadInsert(ST* head, int num, int inum, float iscore)//根据节点,头部插入
{
ST* p1, * p2;
p1 = p2 = NULL;//定义两空节点
p1 = head;
while (p1 != NULL)
{
if (p1->num == num)
{
break;
}
else
{
p2 = p1;//记录当前节点
p1 = p1->next;//循环到下一个节点
}
}
if (head == p1)//头节点
{
ST* newnode = (ST *)malloc(sizeof(ST));
newnode->num = inum;
newnode->score = iscore;
newnode->next = head;//指向第一个节点
head = newnode;//newnode成为第一个节点
}
else
{
ST* newnode = (ST*)malloc(sizeof(ST));
newnode->num = inum;
newnode->score = iscore;
newnode->next = p1;//新节点指向p1
p2->next = newnode;//指向新节点
}
return head;
}
2.8根据节点,尾部插入
ST* BackInsert(ST* head, int num, int inum, float iscore)//根据节点,尾部插入
{
ST* p1, * p2;
p1 = p2 = NULL;//定义两空节点
p1 = head;
while (p1 != NULL)
{
if (p1->num == num)
{
break;
}
else
{
//p2 = p1;//记录当前节点
p1 = p1->next;//循环到下一个节点
}
}
if (p1->next == NULL)//最后一个节点
{
ST* newnode = (ST*)malloc(sizeof(ST));
newnode->num = inum;
newnode->score = iscore;
newnode->next = NULL;
p1->next = newnode;
}
else
{
p2 = p1->next;//记录下一个节点的位置
ST* newnode = (ST*)malloc(sizeof(ST));
newnode->num = inum;
newnode->score = iscore;
newnode->next = p2;//链接下一个节点
p1->next = newnode;//p1指向新节点
}
return head;//无意义
}
2.9节点排序
void sort(ST* head,char ch)//当ch为大于号则从大到小排序,冒泡排序
{
if (ch == '>')
{
for (ST* p1 = head; p1 != NULL; p1 = p1->next)
{
for (ST* p2 = head; p2 != NULL; p2 = p2->next)
{
if (p1->num < p2->num)
{
ST temp;
temp.num = p1->num;
p1->num = p2->num;
p2->num = temp.num;
//再交换score
}
}
}
}
else if (ch == '<')
{
}
}
2.10主程序
int main()
{
struct Student* head = NULL;//头指针,指向节点,从而访问节点
add(&head, 1, 70);
add(&head, 2, 80);
add(&head, 3, 90);
add(&head, 4, 91);
add(&head, 5, 92);
//printf("%d,%f\n", head->num, head->score);//访问数据
//printf("%d,%f\n", head->next->num, head->next->score);
//printf("%d,%f\n", head->next->next->num, head->next->next->score);
head = rev(head);
showall(head);
//head= freeall(head);
//head = NULL;//删除头节点务必让他为空
showall(head);
system("pause");
return 0;
}