链表
前言
链表上学期已经学过了,只不过我学了个寂寞,得重学!!!!!!
复习指针
在C语言中,可以使用指针和动态分配内存函数malloc来实现
指针存储地址
例如:
int *p;
double *t;
这里的指针p只能存储“一个存放整数的内存空间”的地址,指针t则是存储“一个存放浮点数额度内存空间”的地址。
p=&a;
整型指针p存储整型变量a的地址
&是取址符
#include<stdio.h>
int main()
{
int a=10;
int *p;//定义一个指针p
p=&a;
printf("a=%d",*p);
getchar();getchar();
return 0;
}
复习mallloc函数
malloc函数的作用就是从内存中申请分配指定字节大小的内存空间
int *q;
p=(int *)malloc(sizeof(int));
数组模拟链表
链表结点的组成
链表的每个结点由两个部分组成。左边的部分用来存放具体的数值,用整型变量,右边的部分需要存储下一个结点的地址,用指针实现。
struct node
{
int data;
struct node *next;
}
如下图所示:
链表的建立
#include<stdio.h>
#include<stdlib.h>
//创建链表
struct node
{
int data;
struct node *next;
};
int main()
{
struct node *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head=NULL;//头指针为空
for(i=1;i<=n;i++)//循环读入n个数
{
scanf("%d",&a);
p=(struct node*)malloc(sizeof(struct node));
p->data=a;
p->next=NULL;//设置当前结点的后继指针为空
if(head==NULL)
head=p;//如果这是第一个创建的结点,则将头指针指向这个结点
else
q->next=p;//如果这不是第一个创建的结点,则将上一个结点的后继指针执行那个当前结点
q=p;//指针q也指向当前结点
}
//输出链表中的所有数
t=head;
while(t!=NULL)
{
printf("%d ",t->data);
t=t->next;//继续下一个结点
}
getchar();getchar();
return 0;
}
在链表中插入6
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
int main()
{
struct node *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head=NULL;
for(i=1;i<=n;i++)
{
scanf("%d",&a);
p=(struct node*)malloc(sizeof(struct node));
p->data=a;
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
scanf("%d",&a);//读入待插入的数
t=head;
while(t!=NULL)//未到达链表尾部时循环
{
if(t->next==NULL || t->next->data > a)//如果当前结点是最后一个结点或者下一个结点的数值大于待插入数时插入
{
p=(struct node *)malloc(sizeof(struct node));
p->data=a;
p->next=t->next;//新增结点的后继指针 指向 当前结点的后继指针 指向的结点
t->next=p;//当前结点的后继指针指向新增结点
break;//插入完毕,结束循环
}
t=t->next;//继续下一个结点
}
t=head;//输出
while(t!=NULL)
{
printf("%d ",t->data);
t=t->next;
}
getchar();getchar();
return 0;
}
模拟链表
用数组实现链表的方式,叫模拟链表
每个链表中的每一个结点有2个部分,用数组data来存储序列中的每一个数
对于每个数右边的数的位置,上面代码中是用指针表示,下面可以用数组right来表示每个数右边的数的位置。
例如,right[4]=5,则说明当前序列中,第4个数后面一个数在data中的位置是5。
模拟过程
- 先在8之前插入一个数字6,只需将6直接存放在数组data的末尾,data[10]=6
- 再将right[3]改为10,表示新序列中3号元素(5)右边的元素(6)在data[10]中。
- 再将right[10]改为4,表示新序列中10号元素(6)右边的元素(8)在data[4]中。
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int data[101],right[101];
int i,n,t,len;
//读入已有的数
scanf("%d",&n);//现有数字个数n
len=n;
for(i=1;i<=n;i++)
{
if(i!=n)
right[i]=i+1;
else
right[i]=0;
}
//直接在数组data末尾增加一个数
len++;
scanf("%d",&data[len]);//插入的数
//从链表头部开始遍历
t=1;
while(t!=0)
{
if(data[right[t]]>data[len])//一开始data[right[1]]>data[10],data[right[1]]=data[2],将插入的数和第二个数比较
//当前结点的下一个结点的值大于待插入的数,则将数插入中间
{
right[len]=right[t];//新插入的数的下一个结点标号等于当前结点的下一个结点的标号
right[t]=len;
break;
}
t=right[t];
}
//输出链表的所有数
t=1;
while(t!=0)
{
printf("%d ",data[t]);
t=right[t];
}
getchar();getchar();
return 0;
}
right[3]=10,right[10]=4
意会。。。