用指针实现链表
-
我的理解:指针实现的链表表类似一个数组,但又没有数组的固定大小,且在物理上不相邻。
-
图示:
表的几种操作 -
1 创建节点:使用malloc函数,用法为(指针类型*)malloc(sizeof(指针类型)),并返回为分配的内存的地址。
-
2插入节点(表尾插入):利用指针pr寻找表尾,找到后将地址赋给节点p,再对p节点中的数据域和指针域进行操作。
-
3:删除节点:将要删除的节点前一个节点的指针域指向要删除节点的指针域。
-
4:表的删除:每个节点free一次。
#include<stdio.h>
#include<stdlib.h>
struct link *AppendNode(struct link *head);
struct link *DeleteData (struct link *head);
struct link *FoundNode (struct link *head);
struct link *ModifyData(struct link *head);
void DisplayNode(struct link *head);
void DeleteMemory (struct link *head);
struct link{
int data;
struct link *next;
};
int main()
{
int c;
char a='y';
struct link *head = NULL; //定义表头为空
printf("欢迎来到链表中心\n");
while (a == 'y' || a == 'Y'){
printf(" 2 添加数据\n 3删除数据\n 4查找数据\n 5 修改数据\n 6输出链表中所有的数据\n ");
scanf("%d",&c);
switch(c){
case 2:{
head = AppendNode(head);
break;
}
case 3:{
head = DeleteData(head);
break;
}
case 4:{
head =FoundNode (head);
break;
}
case 5:{
head = ModifyData(head);
break;
}
case 6:{
DeleteMemory(head);
break;
}
default :printf("输入错误\n");
}
DisplayNode(head);
printf("按非y键推出菜单");
fflush(stdin);//解决输入缓冲区导致的a读取到上一次的回车键。
scanf("%c",&a);
system("cls");
}
printf("感谢您的使用,再见!");
DeleteMemory(head);
}
struct link *AppendNode(struct link *head){ //声明创建节点函数
struct link *p = NULL,*pr = head; //创建p指针,初始化为NULL;创建pr指针,通过pr指针来给指针域赋值
int data ;
p = (struct link *)malloc(sizeof(struct link)) ; //为指针p申请内存空间,必须操作,因为p是新创建的节点
if(p == NULL){ //如果申请内存失败,则退出程序
printf("NO enough momery to allocate!\n");
exit(0);
}
if(head == NULL){ //如果头指针为NULL,说明现在链表是空表
head = p; //使head指针指向p的地址(p已经通过malloc申请了内存,所以有地址)
}else{ //此时链表已经有头节点 ,再一次执行了AppendNode函数
//注:假如这是第二次添加节点
//因为第一次添加头节点时,pr = head,和头指针一样指向头节点的地址
while(pr->next!= NULL){ //当pr指向的地址,即此时的p的指针域不为NULL(即p不是尾节点)
pr = pr->next; //使pr指向当前节点的指针域,即指向下一个节点
}
pr->next = p; //使pr的指针域指向新键节点的地址,此时的next指针域是头节点的指针域。此时已经连接上
}
printf("Input node data:");
printf("\n");
scanf("%d",&data);
p->data = data; //给节点的数据域赋值
p->next = NULL; //新添加的节点位于表尾,所以它的指针域为NULL
return head; //返回head的地址
}
struct link *FoundNode (struct link *head){
struct link *p = head;
int i=1;
int j;
printf("请输入要查找的数据的序号");
scanf("%d",&j);
while(i < j && p != NULL) {
p = p->next;
i++;
}
printf("%5d号数据 值为%5d",j,p ->data );
return head;
}
struct link *ModifyData(struct link *head){
struct link *p = head;
int i=1;
int j,data;
printf("请输入要修改的数据的序号");
scanf("%d",&j);
while(i<j && p != NULL){
p = p -> next;
i++;
}
printf("Input node data:");
scanf("%d",&data);
p->data = data;
return head;
}
struct link *DeleteData (struct link *head){
struct link *p = head; // 记录删除节点的上一个节点
struct link *pr = head; //用来记录要删除的节点
int i = 0;
int k;
printf("请输入要删除的数据的序号");
scanf("%d",&k);
if(k<2){
printf("输入有误");
exit(0);
}
while(i<k-2 && p != NULL) {
p = p -> next;
i++;
}
i = 0;
while (i<k-1 && pr != NULL) {
pr = pr -> next;
i++;
}
p->next = pr ->next; //进行覆盖节点pr的操作
free(pr);
return head;
}
void DisplayNode (struct link *head){
struct link *p = head;
int j = 1;
while(p != NULL){
printf("%5d%10d\n",j,p -> data);
p = p -> next;
j++;
}
}
void DeleteMemory (struct link *head){
struct link *p = head,*pr = NULL;
while(p != NULL){
pr = p;
p = p -> next;
free(pr);
}
}