数据结构中的链表是可以开辟不连续的空间来存储,那么链表该如何创建和使用呢?
链表的创建
首先创建链表的结构体
struct linklist
{
int data;//数据域
struct linklist*link;//指针域
};
然后链表的创建
linklist* creat(int n){//n是线性链表的长度
int i;
struct linklist*head=(struct linklist*)malloc(sizeof(struct linklist));//创建头指针
head->link=NULL;
if(n==0){
head=NULL;
return head;
}
struct linklist *p;
p=head;
for(i=0;i<n;i++){
if(i==0) //第一次先将数据放入头指针的数据域中
scanf("%d",&head->data);
else{//之后在创建新 的链接点
struct linklist *s=(struct linklist*)malloc(sizeof(struct linklist));
scanf("%d",&s->data);
p->link=s;
s->link=NULL;//链表末尾的指针域为空
p=s;
}
}
return head;
}
链表的一些方法
遍历链表,并且输出
void ergidoc(linklist* s){//遍历整个链表
linklist *p;
p=s;
while(p!=NULL){
printf("%d\t",p->data);
p=p->link;
}
printf("\n");
}
求线性链表的长度
int length(linklist *s){//求线性链表的长度
linklist *p;
p=s;
int n=0;
while(p!=NULL){
p=p->link;
n++;
}
return n;
}
判断链表是不是空链表
int isempty(linklist *S){//判断该链表是不是空表
return S==NULL; //如果是1就是空表,反之则为0
}
返回指定数据的数据域的指针
linklist* find(linklist *s,int w){//找到链表中n的地址
linklist *p;
p=s;
while (p!=NULL && p->data!=w)
{
p=p->link;
}
return p;
}
插入
在链表的末尾加入
void insertlink1(linklist *s,int w){//在末尾加入一个链接点
linklist *p;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->link=NULL;
r->data=w;
p=s;
while(p->link!=NULL){
p=p->link;
}
p->link=r;
}
在链表的首部加入
linklist* insertlink2(linklist *s,int w){//在链表的头部加入一个链接点
linklist *p;
p=s;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->link=p;
r->data=w;
return r;
}
在指定的数据域后插入
linklist* insertlink3(linklist *s,int w,int y){//在指定的data值后面插入一个链接点
linklist *p;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->data=y;
p=s;
while(p!=NULL && p->data!=w){
p=p->link;
}
if (p==NULL){
printf("error\n");
return s;
}
else{
linklist *q;
q=p->link;
p->link=r;
r->link=q;
}
return s;
}
在指定的位置插入
linklist* insertlink4(linklist *s,int w,int y){//在指定的第i个链接点后面插入一个链接点
linklist *p;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->data=y;
p=s;
if (w>length(s)){
printf("errpr\n");
return s;
}
else{
for(int i=0;i<w-1;i++){
p=p->link;
}
linklist *q;
q=p->link;
p->link=r;
r->link=q;
}
return s;
}
删除
删除指定数据域的所有链接点
void remove1(linklist *s,int w){//删除数据域为w的所有链接点
linklist *p;
linklist *q;
q=s;//q在p的前面
p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
while (p!=NULL)
{
if(p->data==w){
q->link=p->link;//使得前面的链接点可以链接到后面
free(p);
p=q->link;
}
else{
q=p;
p=p->link;
}
}
if(s->data==w){//判断第一个链接点
q=s;
s=s->link;
free(q);
}
}
删除指定的链接点
void remove2(linklist *s,linklist *w){//删除p指向的链接点
linklist *p;
linklist* q;
q=s;
p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
while (p!=NULL && p!=w)
{ q=p;
p=p->link;
}
if (p==NULL)
{
printf("error\n");
}
else{
q->link=p->link;
free(p);
}
}
删除整个链表
linklist* remove3(linklist *s){//删除整个链表
linklist *p;
p=s;
while (p!=NULL)
{
s=p->link;
free(p);
p=s;
}
return s;
}
总的代码和示例
#include<stdio.h>
#include<stdlib.h>
struct linklist
{
int data;
struct linklist*link;
};
linklist* creat(int n){//n是线性链表的长度
int i;
struct linklist*head=(struct linklist*)malloc(sizeof(struct linklist));//创建头指针
head->link=NULL;
if(n==0){
head=NULL;
return head;
}
struct linklist *p;
p=head;
for(i=0;i<n;i++){
if(i==0) //第一次先将数据放入头指针的数据域中
scanf("%d",&head->data);
else{//之后在创建新 的链接点
struct linklist *s=(struct linklist*)malloc(sizeof(struct linklist));
scanf("%d",&s->data);
p->link=s;
s->link=NULL;//链表末尾的指针域为空
p=s;
}
}
return head;
}
void ergidoc(linklist* s){//遍历整个链表
linklist *p;
p=s;
while(p!=NULL){
printf("%d\t",p->data);
p=p->link;
}
printf("\n");
}
int length(linklist *s){//求线性链表的长度
linklist *p;
p=s;
int n=0;
while(p!=NULL){
p=p->link;
n++;
}
return n;
}
int isempty(linklist *S){//判断该链表是不是空表
return S==NULL; //如果是1就是空表,反之则为0
}
linklist* find(linklist *s,int w){//找到链表中n的地址
linklist *p;
p=s;
while (p!=NULL && p->data!=w)
{
p=p->link;
}
return p;
}
void insertlink1(linklist *s,int w){//在末尾加入一个链接点
linklist *p;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->link=NULL;
r->data=w;
p=s;
while(p->link!=NULL){
p=p->link;
}
p->link=r;
}
linklist* insertlink2(linklist *s,int w){//在链表的头部加入一个链接点
linklist *p;
p=s;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->link=p;
r->data=w;
return r;
}
linklist* insertlink3(linklist *s,int w,int y){//在指定的data值后面插入一个链接点
linklist *p;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->data=y;
p=s;
while(p!=NULL && p->data!=w){
p=p->link;
}
if (p==NULL){
printf("error\n");
return s;
}
else{
linklist *q;
q=p->link;
p->link=r;
r->link=q;
}
return s;
}
linklist* insertlink4(linklist *s,int w,int y){//在指定的第i个链接点后面插入一个链接点
linklist *p;
linklist *r=(linklist*)malloc(sizeof(linklist));
r->data=y;
p=s;
if (w>length(s)){
printf("errpr\n");
return s;
}
else{
for(int i=0;i<w-1;i++){
p=p->link;
}
linklist *q;
q=p->link;
p->link=r;
r->link=q;
}
return s;
}
void remove1(linklist *s,int w){//删除数据域为w的所有链接点
linklist *p;
linklist *q;
q=s;//q在p的前面
p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
while (p!=NULL)
{
if(p->data==w){
q->link=p->link;//使得前面的链接点可以链接到后面
free(p);
p=q->link;
}
else{
q=p;
p=p->link;
}
}
if(s->data==w){//判断第一个链接点
q=s;
s=s->link;
free(q);
}
}
void remove2(linklist *s,linklist *w){//删除p指向的链接点
linklist *p;
linklist* q;
q=s;
p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
while (p!=NULL && p!=w)
{ q=p;
p=p->link;
}
if (p==NULL)
{
printf("error\n");
}
else{
q->link=p->link;
free(p);
}
}
linklist* remove3(linklist *s){//删除整个链表
linklist *p;
p=s;
while (p!=NULL)
{
s=p->link;
free(p);
p=s;
}
return s;
}
int main(){
linklist* q;
linklist*w;
w=creat(5);//创建链表
insertlink1(w,6);//在末尾加入6
ergidoc(w);//遍历链表
w=insertlink2(w,0);//在链表的头部加入0
ergidoc(w);//遍历链表
insertlink3(w,4,1001);//指定在4的数据域后加入1001
ergidoc(w);//遍历链表
insertlink4(w,8,22222);//在链表的第8个链接点加入22222
ergidoc(w);//遍历链表
printf("%d\n",length(w));//输出链表的长度
printf("%d\n",isempty(w));//判断链表是否为空
remove1(w,2);//移除 数据域为2 的链接点
ergidoc(w);//遍历链表
q=find(w,3);//找到数据域为3 的链接点
remove2(w,q);//删除指定的链接点
ergidoc(w);//遍历链表
w=remove3(w);//删除整个链表
printf("%d\n",isempty(w));//判断链表是否为空
}
这里我输入了5个数是1,2,3,4,5
结果