目录
[7.设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素的元素 (c语言代码实现)](#7.设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素的元素 (c语言代码实现))
8.给定两个单链表,编写算法找出两个链表的公共结点(c语言代码)
[9.给定一个带表头结点的单链表,写出算法 : 按递增次序输出单链表中各结点的数据元素并释放结点 (c语言代码实现)](#9.给定一个带表头结点的单链表,写出算法 : 按递增次序输出单链表中各结点的数据元素并释放结点 (c语言代码实现))
10.将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变(c语言代码)
11.C={a1,b1,a2,b2,...,an,bn}为线性表,采用带头结点的单链表存放,设计一个就地算法,将其拆分为两个线性表,使得A={a1..an},B={bn,.,b1}
7.设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素的元素 (c语言代码实现)
本题代码为(有注释)
void delete(linklist* L, int min, int max)//删除给定的两个值之间的元素
{
lnode* p = (*L)->next, * q = *L;
while (p != NULL)
{
if (p->data > min && p->data < max)//判断在是否在两个值的中间
{
q->next= p->next;//使q的后继指向p的后继
free(p);//释放p的内存
p = q->next;//使p指向q的后继
}
else
{
q = q->next;//q跟p都想后遍历
p = p->next;
}
}
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
int data;
struct lnode* next;
}lnode,*linklist;
int n = 6;
int a[6] = { 3,2,4,9,8,7 };
void buildlinklist(linklist* L)
{
*L = (lnode*)malloc(sizeof(lnode));
(*L)->next = NULL;
int i = 0;
lnode* s = *L, * r = *L;
for (i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
s->next = r->next;
r->next = s;
r = s;
}
r->next = NULL;
}
void delete(linklist* L, int min, int max)//删除给定的两个值之间的元素
{
lnode* p = (*L)->next, * q = *L;
while (p != NULL)
{
if (p->data > min && p->data < max)//判断在是否在两个值的中间
{
q->next= p->next;//使q的后继指向p的后继
free(p);//释放p的内存
p = q->next;//使p指向q的后继
}
else
{
q = q->next;//q跟p都想后遍历
p = p->next;
}
}
}
void print(linklist* L)
{
lnode* k = (*L)->next;
while (k != NULL)
{
printf("%d ", k->data);
k = k->next;
}
}
int main()
{
linklist L;
buildlinklist(&L);
printf("原始单链表为:");
print(&L);
delete(&L,2,6);
printf("\n删除后的单链表为:");
print(&L);
return 0;
}
8.给定两个单链表,编写算法找出两个链表的公共结点(c语言代码)
两个链表有公共结点,就是两个链表从某一结点开始,它们的next都指向同一个结点
本题代码如下
int length(linklist* L)//计算链表长度
{
int j = 0;
lnode* p = (*L)->next;
while (p != NULL)
{
j++;
p = p->next;
}
return j;
}
linklist* findcommon(linklist* L1, linklist* L2)
{
int len1 = length(L1);//计算两个链表的长度
int len2 = length(L2);
int dist = 0;
linklist longlist, shortlist;//分别指向长的链表和短的链表
if (len1 > len2)//L1较长
{
longlist = (*L1)->next;
shortlist = (*L2)->next;
dist = len1 - len2;//表长之差
}
else//L2表长
{
longlist = (*L2)->next;
shortlist = (*L1)->next;
dist = len2 - len1;
}
while (dist--)//表长的先遍历到第dist个结点
longlist = longlist->next;
while (longlist != NULL)//同步寻找共同结点
{
if (longlist->data== shortlist->data)//找到第一个公共结点
return longlist->data;
else//没没找到就继续寻找
{
longlist = longlist->next;
shortlist = shortlist->next;
}
}
return NULL;
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
int data;
struct lnode* next;
} lnode, * linklist;
int a[5] = { 1,3,5,6,7};
int b[4] = { 2,9,6,7};
int n1 = 5;
int n2 = 4;
void buildlinklist(linklist* L, int arr[], int n)
{
*L = (lnode*)malloc(sizeof(lnode));
(*L)->next = NULL;
int i = 0;
lnode* s = *L, * r = *L;
for (i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = arr[i];
s->next = r->next;
r->next = s;
r = s;
}
r->next = NULL;
}
int length(linklist* L)//计算链表长度
{
int j = 0;
lnode* p = (*L)->next;
while (p != NULL)
{
j++;
p = p->next;
}
return j;
}
linklist* findcommon(linklist* L1, linklist* L2)
{
int len1 = length(L1);//计算两个链表的长度
int len2 = length(L2);
int dist = 0;
linklist longlist, shortlist;//分别指向长的链表和短的链表
if (len1 > len2)//L1较长
{
longlist = (*L1)->next;
shortlist = (*L2)->next;
dist = len1 - len2;//表长之差
}
else//L2表长
{
longlist = (*L2)->next;
shortlist = (*L1)->next;
dist = len2 - len1;
}
while (dist--)//表长的先遍历到第dist个结点
longlist = longlist->next;
while (longlist != NULL)//同步寻找共同结点
{
if (longlist->data== shortlist->data)//找到第一个公共结点
return longlist->data;
else//没没找到就继续寻找
{
longlist = longlist->next;
shortlist = shortlist->next;
}
}
return NULL;
}
int main()
{
linklist L1;
linklist L2;
linklist L3 = (lnode*)malloc(sizeof(lnode));
buildlinklist(&L1, a, n1);
buildlinklist(&L2, b, n2);
L3->data= findcommon(&L1, &L2);
if (L3 != NULL)
{
printf("找到公共节点: %d\n", L3->data);
}
else
{
printf("没有找到公共节点\n");
}
return 0;
}
9.给定一个带表头结点的单链表,写出算法 : 按递增次序输出单链表中各结点的数据元素并释放结点 (c语言代码实现)
本题代码如下(有注释)
void delete_min(linklist* head)
{
while ((*head)->next != NULL)//循环到只剩下头节点
{
lnode* pre = *head;//pre为元素最小结点的前驱结点指针
lnode* p = (*head)->next;//p为工作指针
lnode* q;//指向被删除的结点
while (p->next != NULL)//找到最小的结点
{
if (p->next->data < pre->next->data)
pre = p;//记住当前最小值的前驱
p = p->next;
}
printf("%d ", pre->next->data);//输出最小值结点的数据
q = pre->next;//p指向最小结点
pre->next = q->next;//pre后继指向q的后继
free(q);//释放q结点
}
free(*head);//释放头节点
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
int data;
struct lnode* next;
}lnode,*linklist;
int n = 5;
int a[5] = { 2,1,9,8,7 };
void buildlinklist(linklist* head)//建立单链表
{
*head = (lnode*)malloc(sizeof(lnode));
(*head)->next = NULL;
int i = 0;
lnode* s = *head, * r = *head;
for (i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
s->next = r->next;
r->next = s;
r = s;
}
r->next = NULL;
}
void delete_min(linklist* head)
{
while ((*head)->next != NULL)//循环到只剩下头节点
{
lnode* pre = *head;//pre为元素最小结点的前驱结点指针
lnode* p = (*head)->next;//p为工作指针
lnode* q;//指向被删除的结点
while (p->next != NULL)//找到最小的结点
{
if (p->next->data < pre->next->data)
pre = p;//记住当前最小值的前驱
p = p->next;
}
printf("%d ", pre->next->data);//输出最小值结点的数据
q = pre->next;//p指向最小结点
pre->next = q->next;//pre后继指向q的后继
free(q);//释放q结点
}
free(*head);//释放头节点
}
int main()
{
linklist head;
buildlinklist(&head);
delete_min(&head);
return 0;
}
10.将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变(c语言代码)
设置一个访问变量(初值为0),每访问一个结点序号自动加1,然后根据序号的奇偶性将结点插入到A表或B表中,用while循环重复以上操作直到表尾
本题代码如下
linklist discreat(linklist* L)
{
lnode* B = (lnode*)malloc(sizeof(lnode));//创建B表的表头
B->next = NULL;//B表初始化
int i = 0;
lnode* p = (*L)->next;//p为工作指针
lnode* ra = *L,*rb=B;//ra指向A表尾,rb指向B表尾
while (p != NULL)
{
i++;
if (i % 2 == 0)//处理偶数序列的链表结点
{
rb->next = p;
rb = p;
}
else//处理原序号为奇数的结点
{
ra->next = p;
ra = p;
}
p = p->next;//p指向下一个待处理的结点
}
ra->next = NULL;
rb->next = NULL;
return B;
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
int data;
struct lnode* next;
}lnode,*linklist;
int n = 6;
int a[6] = { 1,2,3,4,5,6 };
void buildlinklist(linklist* L)
{
*L = (lnode*)malloc(sizeof(lnode));
(*L)->next = NULL;
lnode* s = *L, * r = *L;
int i = 0;
for (i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
s->next = r->next;
r->next = s;
r = s;
}
r->next =NULL;
}
linklist discreat(linklist* L)
{
lnode* B = (lnode*)malloc(sizeof(lnode));//创建B表的表头
B->next = NULL;//B表初始化
int i = 0;
lnode* p = (*L)->next;//p为工作指针
lnode* ra = *L,*rb=B;//ra指向A表尾,rb指向B表尾
while (p != NULL)
{
i++;
if (i % 2 == 0)//处理偶数序列的链表结点
{
rb->next = p;
rb = p;
}
else//处理原序号为奇数的结点
{
ra->next = p;
ra = p;
}
p = p->next;//p指向下一个待处理的结点
}
ra->next = NULL;
rb->next = NULL;
return B;
}
void print(linklist* L)//输出单链表
{
lnode* q = (*L)->next;
while (q)
{
printf("%d ", q->data);
q = q->next;
}
}
int main()
{
linklist L,B;
buildlinklist(&L);
printf("原始单链表为:");
print(&L);
B=discreat(&L);
printf("\nA链表为:");
print(&L);
printf("\nB链表为:");
print(&B);
return 0;
}
11.C={a1,b1,a2,b2,...,an,bn}为线性表,采用带头结点的单链表存放,设计一个就地算法,将其拆分为两个线性表,使得A={a1..an},B={bn,.,b1}
本题A链表应用尾插法,B链表应用头插法
linklist chaifen(linklist* L)//A链表用尾插法,B链表用头插法
{
lnode* B = (lnode*)malloc(sizeof(lnode));
B->next = NULL;
lnode* p = (*L)->next, * ra = *L, * q;//p为工作指针,ra始终指向A的为结点
while (p != NULL)
{
ra->next = p;
ra = p;//将*p链接到A的表尾
p = p->next;
if (p != NULL)
{
q = p->next;//用q记录p的后继
p->next = B->next;//将*p插入到B的前端
B->next = p;
p = q;
}
}
ra->next = NULL;//A为结点的next域置空
return B;
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
int data;
struct lnode* next;
}lnode,*linklist;
int n = 6;
int a[6] = { 1,2,3,4,5,6 };
void buildlinklist(linklist* L)
{
*L = (lnode*)malloc(sizeof(lnode));
(*L)->next = NULL;
int i = 0;
lnode* s = *L, * r = *L;
for (i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
s->next = r->next;
r->next = s;
r = s;
}
r->next = NULL;
}
linklist chaifen(linklist* L)//A链表用尾插法,B链表用头插法
{
lnode* B = (lnode*)malloc(sizeof(lnode));
B->next = NULL;
lnode* p = (*L)->next, * ra = *L, * q;//p为工作指针,ra始终指向A的为结点
while (p != NULL)
{
ra->next = p;
ra = p;//将*p链接到A的表尾
p = p->next;
if (p != NULL)
{
q = p->next;//用q记录p的后继
p->next = B->next;//将*p插入到B的前端
B->next = p;
p = q;
}
}
ra->next = NULL;//A为结点的next域置空
return B;
}
void print(linklist* L)//输出单链表
{
lnode* k = (*L)->next;
while (k)
{
printf("%d ", k->data);
k = k->next;
}
}
int main()
{
linklist L, B;
buildlinklist(&L);
printf("原始单链表为:");
print(&L);
B = chaifen(&L);
printf("\nA链表为:");
print(&L);
printf("\nB链表为:");
print(&B);
return 0;
}
12.在一个递增有序的线性表中,有数值相同的元素存在。
若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素,例如(7,10,10,21,30,42,42,42,51,70)将变为(7,10,21,30,42,51,70)。
由于是有序表,所有相同值域的结点都是相邻的。用p扫描递增单链表L,若*p结点的值域等于其后继结点的值域,则删除后者,否则p移向下一个结点
本题代码如下
void deleterepeat(linklist* L)//删除重复的元素
{
lnode* p = (*L)->next, * q;//p为扫描工作指针
while (p->next!= NULL)
{
q = p->next;//q指向p的后继
if (p->data == q->data)//如果p的后继与p相等
{
p->next = q->next;//p的后继就指向q的后继,也就是p的后继的后继
free(q);//释放q结点
}
else
{
p = p->next;//p继续往后遍历
}
}
}
完整测试代码
#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
int data;
struct lnode* next;
}lnode,*linklist;
int n = 10;
int a[10] = { 7,10,10,21,30,42,42,42,51,70 };
void buildlinklist(linklist* L)
{
*L = (lnode*)malloc(sizeof(lnode));
(*L)->next = NULL;
lnode* s = *L, * r = *L;
int i = 0;
for (i = 0; i < n; i++)
{
s = (lnode*)malloc(sizeof(lnode));
s->data = a[i];
s->next = r->next;
r->next = s;
r = s;
}
r->next = NULL;
}
void deleterepeat(linklist* L)//删除重复的元素
{
lnode* p = (*L)->next, * q;//p为扫描工作指针
while (p->next!= NULL)
{
q = p->next;//q指向p的后继
if (p->data == q->data)//如果p的后继与p相等
{
p->next = q->next;//p的后继就指向q的后继,也就是p的后继的后继
free(q);//释放q结点
}
else
{
p = p->next;//p继续往后遍历
}
}
}
void print(linklist* L)//输出的单链表
{
lnode* k = (*L)->next;
while (k != NULL)
{
printf("%d ", k->data);
k = k->next;
}
}
int main()
{
linklist L;
buildlinklist(&L);
printf("原单链表为:");
print(&L);
deleterepeat(&L);
printf("\n修改后的链表为:");
print(&L);
return 0;
}