考研数据结构中的代码如何写——线性表的链式存储

本文深入探讨了链表的基础知识,包括指针、结构体和链表的概念。通过实例展示了如何初始化、输出、删除特定值、反向输出、删除最小值、逆置、排序以及删除范围内的元素等链表操作。文章覆盖了单链表的各种常见问题,为读者提供了清晰的思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表我认为基本是考研代码题目中最经常出现的题型了,想要写好这部分的代码,首相得搞清楚几个概念。

指针:简单的说就是存储地址的变量,我们都知道,程序中定义的变量,都会在内存中分配一块空间,归根结底,都是通过地址查找变量,运算。请看下面一个简单的代码:

int *p;//定义一个指向整型数据的指针变量

int a = 0;//定义一个整型变量

p = &a;//p指向a变量的首地址

printf("%d",*p);//*p取地址指向的元素值,即输出0

如果上面说的都能理解,那么我觉得你完全有能力搞定链表部分的代码。

结构体:用户自定义的数据类型,例如:

struct student//定义一个结构体类型

{

        int num;//结构体的成员

        char *name;

};

struct student stu;//定义一个结构体变量

stu.num = 2016212056;// 给结构体变量的成员赋值

*(stu.name) = "hd";//也可以写成stu->name = "hd"

printf("%d\n%s",stu.num,*(stu.name) );

输出结果:

2016212056

hd

链表:线性表的链式存储,逻辑上相邻的元素,物理上不一定相邻,除第一个结点外,每一个结点都有一个直接前驱,除最后一个结点外,每一个结点都有一个直接后继。

typedef struct LNode

{

        int data;

        struct LNode *next;

}Lnode,*LinkList;

下面来看一个简单的初始化一个单链表的例子:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 2;
    p4->data = 3;
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}

该单链表的结构如图所示:

运行结果:

说到这里,基本上该准备的导学知识就差不多了,把上面这些弄明白,写链表的代码题是不成问题的,无论是不带头结点的单链表,带头结点的单链表,不带头节点的循环单链表,带头节点的循环单链表,不带头节点的双链表,带头结点的双链表,不带头节点的循环双链表,带头结点的循环双链表都能迎刃而解,如庖丁解牛,知道其中的架构,就知道从哪儿动手了,下面我还是会给出王道书上的代码解答。

1.设计一个递归算法,删除不带头结点的单链表L中的所有值为x的结点。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void del_elem(LinkList &L,int x);//删除元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    del_elem(L,1);
    printf("\n");
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 1;
    p4->data = 3;
    p5->data = 4;
    p6->data = 5; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void del_elem(LinkList &L,int x)
{
	LNode *p,*q;
	p = L;
	if(L == NULL)//递归出口 
	{
		return;	
	} 
	if(L->data == x)
	{
		q = L;
		L = L->next;
		free(q);
		del_elem(L,x);
		
	}
	else
	{
		del_elem(L->next,x);
	}
} 

运行结果:

参考答案:

typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;

void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void del_elem(LinkList &L,int x)
{
	LNode *p,*q;
	p = L;
	if(L == NULL)//递归出口 
	{
		return;	
	} 
	if(L->data == x)
	{
		q = L;
		L = L->next;
		free(q);
		del_elem(L,x);
		
	}
	else
	{
		del_elem(L->next,x);
	}
} 

2.在带头结点的单链表中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法以实现以上操作。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void del_elem(LinkList &L,int x);//删除元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    del_elem(L,1);
    printf("\n");
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 1;
    p4->data = 3;
    p5->data = 1;
    p6->data = 1; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void del_elem(LinkList &L,int x)
{
	LNode *p,*q,*pre;
	p = L;
	if(p->next == NULL)//空链表 
	{
		printf("null linklist");
	}
	pre = p;//pre前指针,方便单链表的删除操作 
	while(p->next !=NULL)//判断p的指针域是否为空 
	{
		
		p = p->next;//p指针后移 
		if(p->data == x)//删除值为x的结点 
		{
			q = p;
			pre->next = p->next;
			p = pre;
			free(q);
		}
		else
		{
			
			pre = pre->next; 
		}
	}
	
	
} 

运行结果:

参考答案:

typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;

void del_elem(LinkList &L,int x)
{
	LNode *p,*q,*pre;
	p = L;
	if(p->next == NULL)//空链表 
	{
		printf("null linklist");
	}
	pre = p;//pre前指针,方便单链表的删除操作 
	while(p->next !=NULL)//判断p的指针域是否为空 
	{
		
		p = p->next;//p指针后移 
		if(p->data == x)//删除值为x的结点 
		{
			q = p;
			pre->next = p->next;
			p = pre;
			free(q);
		}
		else
		{
			pre = pre->next; 
		}
	}
	
	
} 

3.设L为带头结点的单链表,编写算法实现从尾到头反向输出每个结点的值。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void reserve_output_elem(LinkList &L);//删除元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    printf("\n");
    reserve_output_elem(L);
    
    //output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 1;
    p4->data = 3;
    p5->data = 1;
    p6->data = 1; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void reserve_output_elem(LinkList &L)
{
	/*先用头插法就地逆置*/
	LNode *p,*q,*pre;
	p = L->next;

	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	L->next = NULL;
	while(p != NULL)//头插法依此插入结点 
	{
		q = p;
		p = p->next;
		q->next = L->next;
		L->next = q;
	}
	p = L->next;
	while(p != NULL)//遍历输出 
	{
		printf("%d->",p->data);
		p = p->next;
	}
	
	
	
} 

运行结果:

 

参考答案:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void reserve_output_elem(LinkList &L);//删除元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    printf("\n");
    reserve_output_elem(L);
    
    //output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 1;
    p4->data = 3;
    p5->data = 1;
    p6->data = 1; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void reserve_output_elem(LinkList &L)
{
	/*先用头插法就地逆置*/
	LNode *p,*q,*pre;
	p = L->next;

	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	L->next = NULL;
	while(p != NULL)//头插法依此插入结点 
	{
		q = p;
		p = p->next;
		q->next = L->next;
		L->next = q;
	}
	p = L->next;
	while(p != NULL)//遍历输出 
	{
		printf("%d->",p->data);
		p = p->next;
	}
	
	
	
} 

4.试编写在头结点的单链表L中删除最小值结点的高效算法,假设最小值结点是惟一的。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void del_min(LinkList &L);//删除最小值元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    del_min(L);
    printf("\n");
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 2;
    p4->data = 3;
    p5->data = 4;
    p6->data = -5; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void del_min(LinkList &L)
{
	LNode *p,*q,*pre;
	p = L->next;
	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	int min = p->data;
	while(p->next !=  NULL)//找到最小值 
	{
		p = p->next;
		if(p ->data < min)
		{
			min = p->data;	
		} 
	}
	pre = L;//更新指针,pre指针,常用在单链表中,方便删除操作 
	while(pre->next != NULL)
	{
		if(pre->next->data ==min)//删除 pre->next结点 
		{
			q = pre->next;
			pre->next = q->next;
			free(q); 
			break;
			
		}
		pre = pre->next;
	}
	
	
} 

运行结果:

 

参考答案:

typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void del_min(LinkList &L)
{
	LNode *p,*q,*pre;
	p = L->next;
	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	int min = p->data;
	while(p->next !=  NULL)//找到最小值 
	{
		p = p->next;
		if(p ->data < min)
		{
			min = p->data;	
		} 
	}
	pre = L;//更新指针,pre指针,常用在单链表中,方便删除操作 
	while(pre->next != NULL)
	{
		if(pre->next->data ==min)//删除 pre->next结点 
		{
			q = pre->next;
			pre->next = q->next;
			free(q); 
			break;
			
		}
		pre = pre->next;
	}
	
	
} 

5.试编写算法将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度是O(1)。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void reserve_elem(LinkList &L);//删除元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    printf("\n");
    reserve_elem(L);
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 1;
    p4->data = 3;
    p5->data = 1;
    p6->data = 1; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void reserve_elem(LinkList &L)
{
	/*先用头插法就地逆置*/
	LNode *p,*q,*pre;
	p = L->next;

	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	L->next = NULL;
	while(p != NULL)//头插法依此插入结点 
	{
		q = p;
		p = p->next;
		q->next = L->next;
		L->next = q;
	}
	p = L->next;
	
	
	
	
} 

运行结果:

 

参考答案:

typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;

void reserve_elem(LinkList &L)
{
	/*先用头插法就地逆置*/
	LNode *p,*q,*pre;
	p = L->next;

	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	L->next = NULL;
	while(p != NULL)//头插法依此插入结点 
	{
		q = p;
		p = p->next;
		q->next = L->next;
		L->next = q;
	}
	p = L->next;
	
	
	
	
} 

6.有一个带头结点的单链表L,设计一个算法使其元素递增有序。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void sort_elem(LinkList &L);//删除最小值元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    sort_elem(L);
    printf("\n");
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 5;//给结点的数据域赋值 
    p2->data = 4;
    p3->data = 3;
    p4->data = -2;
    p5->data = 1;
    p6->data = 0; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void sort_elem(LinkList &L)
{
	LNode *p,*q,*pre,*s;
	p = L->next;
	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	s = p->next;
	p->next = NULL;//断开链 
	pre = L;
	while(s != NULL)
	{
		q = s;
		while(pre->next != NULL)//找到插入的位置pre 
		{
			if(pre->next->data > q->data)
			{
			
				break;
			}
			else
			{
				pre = pre->next;
			}
		}	
		/*q插入到pre之后*/
		s = q->next;//s指针后移,用于下次循环 
		p = pre->next;
		pre ->next = q;
		q->next = p; 
		pre = L;//pre指针回到最初位置 
	}

	
	
} 

运行结果:

 

参考答案:

typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;

void sort_elem(LinkList &L)
{
	LNode *p,*q,*pre,*s;
	p = L->next;
	if(p == NULL)//空链表 
	{
		printf("null linklist");
	}
	s = p->next;
	p->next = NULL;//断开链 
	pre = L;
	while(s != NULL)
	{
		q = s;
		while(pre->next != NULL)//找到插入的位置pre 
		{
			if(pre->next->data > q->data)
			{
			
				break;
			}
			else
			{
				pre = pre->next;
			}
		}	
		/*q插入到pre之后*/
		s = q->next;//s指针后移,用于下次循环 
		p = pre->next;
		pre ->next = q;
		q->next = p; 
		pre = L;//pre指针回到最初位置 
	}

	
	
} 

7.设在一个带表头结点的单链表中所有元素结点的数据无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素(若存在)。

程序:

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;
void init_linklist(LinkList &L);//链表初始化函数的声明 
void output_linklist(LinkList L);//输出链表结点元素值的声明 
void del_range(LinkList &L,int m,int n);//删除范围元素的函数声明 
int main(void)
{
    LinkList L;
    init_linklist(L);
    output_linklist(L);
    del_range(L,1,4);
    printf("\n");
    output_linklist(L);
    return 0;

}
void init_linklist(LinkList &L)
{
	/*初始化了一个带头节点的链表*/
    L =  (LNode *)malloc(sizeof(LNode));//为链表分配内存空间 
    LNode *p,*p1,*p2,*p3,*p4,*p5,*p6;
    p = L;
    p1 =  (LNode *)malloc(sizeof(LNode));
    p2 =  (LNode *)malloc(sizeof(LNode));
    p3 =  (LNode *)malloc(sizeof(LNode));
    p4 =  (LNode *)malloc(sizeof(LNode));
    p5 =  (LNode *)malloc(sizeof(LNode));
    p6 =  (LNode *)malloc(sizeof(LNode));
    p1->data = 0;//给结点的数据域赋值 
    p2->data = 1;
    p3->data = 2;
    p4->data = 3;
    p5->data = 4;
    p6->data = 2; 
    p->next = p1;//给结点的指针域赋值,即把链表连起来 
    p1->next = p2;
    p2->next = p3;
    p3->next = p4;
    p4->next = p5;
    p5->next = p6;
    p6->next = NULL;

}
void output_linklist(LinkList L)
{
    LNode *p;
    p = L;
    if (p->next == NULL)//空链表 
    {
        /* code */
        printf("null linklist");
    }
    while (p->next != NULL)//当p的指针域为空的时候跳出循环 
    {
        /* code */
        printf("%d->",p->next->data);
        p = p->next;
    }
    
}
void del_range(LinkList &L,int m,int n)
{
	LNode *p,*q,*pre;
	pre = L;
	if(pre->next == NULL)//空链表 
	{
		printf("null linklist");
	}
	
	while(pre->next != NULL)//pre方便删除操作 
	{
		if(pre->next->data > m && pre->next->data < n)//满足条件时,将pre之后的结点删除 
		{
			q = pre->next;
			p = q->next;
			pre->next = p;
			free(q); 
			 
		}
		else//不满足,pre指针后移 
		{
			pre = pre->next;
		}
	
	}
	
} 

运行结果:

 

参考答案:

typedef struct LNode
{
    int data;
    struct LNode *next;

}Lnode,*LinkList;

void del_range(LinkList &L,int m,int n)
{
	LNode *p,*q,*pre;
	pre = L;
	if(pre->next == NULL)//空链表 
	{
		printf("null linklist");
	}
	
	while(pre->next != NULL)//pre方便删除操作 
	{
		if(pre->next->data > m && pre->next->data < n)//满足条件时,将pre之后的结点删除 
		{
			q = pre->next;
			p = q->next;
			pre->next = p;
			free(q); 
			 
		}
		else//不满足,pre指针后移 
		{
			pre = pre->next;
		}
	
	}
	
} 

8.给定两个单链表,编写算法找出两个链表的公共结点。

程序:

运行结果:

参考答案:

9.给定一个带表头结点的单链表,设head为头指针,结点结构为(data,next),data为整形元素,next为指针,试写出算法:按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间(要求:不允许使用数组作为辅助空间)。

程序:

运行结果:

参考答案:

10.将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变。

程序:

运行结果:

参考答案:

11.设C= {a1, b1,a2,b2, .... an, bn}为线性表, 采用带头结点的hc单链表存放,设计一个就地算法,将其拆分为两个线性表,使得A= {a1,a2,……,an},B={bn,……,b2,b1}。

程序:

运行结果:

参考答案:


12. 在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素。例如(7, 10, 10, 21,30, 42, 42, 42, 51, 70)将变为(7, 10, 21, 30, 42, 51, 70)。

程序:

运行结果:

参考答案:


13. 假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。

程序:

运行结果:

参考答案:


14.设A和B是两个单链表(带头结点),其中元素递增有序。 设计一个算法从A和B中的公共元素产生单链表C,要求不破坏A 、B的结点。

程序:

运行结果:

参考答案:


15.已知两个链表A和B分别表示两个集合,其元素选增排列,编制函数,求A与B的交集,并存放于A链表中。

程序:

运行结果:

参考答案:

16.两个整数序列A=a1, a2, a3,....,am和B= b1, b2, b3,....,bn已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的连续子序列。

程序:

运行结果:

参考答案:

17.设计一个算法用于判断带头结点的循环双链表是否对称。

程序:

运行结果:

参考答案:


18. 有两个循环单链表,链表头指针分别为h1和h2,编写一个函数将链表h2链接到链表h1之后,要求链接后的链表仍保持循环链表形式。

程序:

运行结果:

参考答案:

19.设有一个带头结点的循环单链表,其结点值均为正整数。设计一个算法,反复找出单链表中结点值最小的结点并输出,然后将该结点从中删除,直到单链表空为止,再删除表头结点。

程序:

运行结果:

参考答案:


20.设头指针为L的带有表头结点的非循环双向链表,其每个结点中除有pred (前驱指针)、data (数据)和next (后继指针)域外,还有一个访问频度域freq. 在链表被启用前,其值均初始化为零。每当在链表中进行一次Locate(L,x)运算时, 令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点前面,以便使频繁访问的结点总是靠近表头。试编写符合_上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。

程序:

运行结果:

参考答案:


21. [2009 统考真题]已知一个带有表头结点的单链表,结点结构为 [data][link]假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data域的值,并返回1;否则,只返回0.要求:

1)描述算法的基本设计思想。

2)描述算法的详细实现步骤。

3)根据设计思想和实现步骤,采用程序设计语言描述算法(使用C、C++或Java语言实现),关键之处请给出简要注释。

程序:

运行结果:

22. [2012统考真题]假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,可共享相同的后缀存储空间,例如,"loading" 和"being” 的存储映像如下图所示。



设strl和str2分别指向两个单词所在单链表的头结点,链表结点结构为data|next,请设计一个时间上尽可能高效的算法,找出由strl和str2所指向两个链表共同后缀的起始位置(如图中字符i所在结点的位置p).要求:

1)给出算法的基本设计思想。

2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。

3)说明你所设计算法的时间复杂度。

程序:

运行结果:


23. [2015统考真题] 用单链表保存m个整数,结点的结构为[data] [link],且|data|<=n(n为正整数)。现要求设计一个时间复杂度尽可能高效的算法,对于链表中data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表head如下:

 

则删除结点后的head为


要求:

1)给出算法的基本设计思想。

2)使用C或C++语言,给出单链表结点的数据类型定义。

3)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。4)说明你所设计算法的时间复杂度和空间复杂度。

程序:

运行结果:

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值