您的位置:首页 > 理论基础 > 数据结构算法

数据结构 【实验4 链表其它操作】

2014-04-03 15:36 387 查看
实验要求:

实验4  链表其它操作
实验目的
1.熟悉对单链表的一些其它操作。
2.掌握循环链表和双链表的一些操作,理解与单链表操作的不同。
实验内容
程序1
设单链表L是一个非递减有序表,写一算法将x插入其中后仍保持L的有序性。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                     /*建立链表*/
void InsertList(LinkedList L,int x)              /*插入结点*/
void print(LinkedList L);                         /*输出链表中的结点*/
程序2
利用原空间,将两个单链表合并成一个单链表。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                          /*建立链表*/
LinkedList ListConcat(LinkedList La,LinkedList Lb)   /*合并链表*/
void print(LinkedList L);                         /*输出链表中的结点*/
程序3
已知两个非递减有序的单链表la和lb,将la和lb合并成一个线性表lc,lc也非递减有序。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                     /*建立链表*/
LinkedList union(LinkedList La,Lb)                /*合并链表*/
void print(LinkedList Lc);                         /*输出链表中的结点*/
程序4
已知一个单链表,利用原表把单链表逆置。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                     /*建立链表*/
void List_reverse(LinkedList L)                   /*逆置链表*/
void print(LinkedList L);                         /*输出链表中的结点*/
程序5
在计算机上先输入一串正整数的序列。请编写一个程序,首先用链表存储该序列。然后执行删除操作,即先从链表中找出最小的结点,删除它。然后再在剩余的链表中,找出最小的结点,再删除之。直至表空为止。
设计要求:在程序中构造四个子程序分别为
LinkedList  LinkedListCreat( )                 /*建立链表*/
int min(LinkedList head);                      /*求链表中的最小结点*/
LinkedList del(LinkedList head, int num);   /*删除结点*/
void print(LinkedList L);                      /*输出链表中的结点*/
程序6
利用单循环链表作为存储结构,实现实验二中的约瑟夫环问题。
设计要求:在程序中构造三个子程序分别为
CiLinkList  CiLinkListCreat( )              /*建立不带头结点的单循环链表*/
void del(CiLinkList last, int N, int K)   /*依次输出符合要求的结点*/
void print(CiLinkList L);                   /*输出链表中的结点*/
程序7
在双向链表上实现线性表的下列运算:
a)         建立 DLinkedList  creat()
b)        插入void  DlistInsert(DLinkedList L,int x,int i)
c)        删除void  DlistDelete(DLinkedList L,int i)
程序8
设有一个双链表,每个结点中除有prior,next及data〔可设为正整数〕三个域之外,还有一个专门记录访问该结点次数的数据域freq,其值在初始化时为零。每当在链表中进行一次Search〔l,key〕时,则数据域data之值等于key的结点,其freq域之值将加一。并使该双链表中结点按freq之值的递减顺序排列,freq值越大的结点越靠近表头。请编写符合上述要求的Search〔l,key〕程序。
设计要求:在程序中构造三个子程序分别为
DLinkedList Creat()                          /*建立链表*/
void Search(DLinkedList head,int key)    /*查找链表中符合要求的结点*/
void print(DLinkedList head);              /*输出链表中的结点*/


[b]  参考代码:[/b]

/*    程序1
设单链表L是一个非递减有序表,写一算法将x插入其中后仍保持L的有序性。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                     //建立链表
void InsertList(LinkedList L,int x)              //插入结点
void print(LinkedList L);                         //输出链表中的结点
*/
#include <stdio.h>
#include <malloc.h>
/* 单链表的结点类型 */
typedef struct LNode{
int data;
LNode* next;
}LNode,*LinkedList;

LinkedList  LinkedListCreat( )                     //建立链表
{
LinkedList head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
printf("请输入链表大小:(最多1000个)\n");
int n,i,j,a[1001];
scanf("%d",&n);
printf("请输入链表的所有元素:\n");
for(i=1;i<=n;i++)    //输入元素
scanf("%d",&a[i]);
//冒泡排序
for(i=1;i<n;i++)
for(j=1;j<=n-i;j++)
if(a[j]>a[j+1]){
int t;
t=a[j];a[j]=a[j+1];a[j+1]=t;
}
//尾插法创建链表
LinkedList p = head;
for(i=1;i<=n;i++){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = a[i];
t->next = NULL;
p->next = t;
p = t;
}
return head;
}
void InsertList(LinkedList L,int x)              //插入结点
{
LinkedList p = L->next,pre = L;
while(p){
if(x < p->data){    //插在pre后面,p前面
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = x;
t->next = p;
pre->next = t;
break;
}
pre = p;
p = p->next;
}
if(p==NULL){    //如果这个数比链表中任何一个数都大
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = x;
t->next = NULL;
pre->next = t;
}
}

void print(LinkedList L)                       //输出链表中的结点
{
LinkedList p=L->next;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int x;
printf("设单链表L是一个非递减有序表,将x插入其中后仍保持L的有序性。\n");
LinkedList head = LinkedListCreat();
printf("请输入要插入的元素值:\n");
while(scanf("%d",&x)!=EOF){
InsertList(head,x);
printf("插入之后的单链表:\n");
print(head);
printf("---------------------\n");
printf("请输入要插入的元素值:\n");
}
return 0;
}


/* 程序2
利用原空间,将两个单链表合并成一个单链表。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                          //建立链表
LinkedList ListConcat(LinkedList La,LinkedList Lb)   //合并链表
void print(LinkedList L);                         //输出链表中的结点
*/
#include <stdio.h>
#include <malloc.h>
/* 单链表的结点类型 */
typedef struct LNode{
int data;
LNode* next;
}LNode,*LinkedList;

LinkedList  LinkedListCreat( )                     //建立链表
{
LinkedList head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
printf("请输入链表大小:(最多1000个)\n");
int n,i,a[1001];
scanf("%d",&n);
printf("请输入链表的所有元素:\n");
for(i=1;i<=n;i++)    //输入元素
scanf("%d",&a[i]);
//尾插法创建链表
LinkedList p = head;
for(i=1;i<=n;i++){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = a[i];
t->next = NULL;
p->next = t;
p = t;
}
return head;
}

LinkedList ListConcat(LinkedList La,LinkedList Lb)   //合并链表
{
LinkedList head = La;
while(La->next){    //找到La的最后一个节点
La = La->next;
}
La->next = Lb->next;    //把La的最后一个节点和La的第一个节点连接上
return head;
}

void print(LinkedList L)                       //输出链表中的结点
{
LinkedList p=L->next;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}

int main()
{
printf("利用原空间,将两个单链表合并成一个单链表。\n");
printf("1.创建单链表La\n");
LinkedList La = LinkedListCreat();
printf("2.创建单链表Lb\n");
LinkedList Lb = LinkedListCreat();
printf("3.合并单链表\n");
LinkedList Lc = ListConcat(La,Lb);
printf("合并成功!\n");
printf("4.输出合并后的链表\n");
print(Lc);
return 0;
}


/* 程序3
已知两个非递减有序的单链表la和lb,将la和lb合并成一个线性表lc,lc也非递减有序。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                     //建立链表
LinkedList union(LinkedList La,Lb)                //合并链表
void print(LinkedList Lc);                         //输出链表中的结点
*/
#include <stdio.h>
#include <malloc.h>
/* 单链表的结点类型 */
typedef struct LNode{
int data;
LNode* next;
}LNode,*LinkedList;

LinkedList  LinkedListCreat( )                     //按顺序建立链表
{
LinkedList head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
printf("请输入链表大小:(最多1000个)\n");
int n,i,j,a[1001];
scanf("%d",&n);
printf("请输入链表的所有元素:\n");
for(i=1;i<=n;i++)    //输入元素
scanf("%d",&a[i]);
//冒泡排序
for(i=1;i<n;i++)
for(j=1;j<=n-i;j++)
if(a[j]>a[j+1]){
int t;
t=a[j];a[j]=a[j+1];a[j+1]=t;
}
//尾插法创建链表
LinkedList p = head;
for(i=1;i<=n;i++){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = a[i];
t->next = NULL;
p->next = t;
p = t;
}
return head;
}

LinkedList Union(LinkedList La,LinkedList Lb)                //合并链表
{
LinkedList head =  (LNode*)malloc(sizeof(LNode));
LinkedList p = head;
La = La->next,Lb = Lb->next;
while(La && Lb){    //比较,直到其中一个链表比较完
if(La->data < Lb->data){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = La->data;
t->next = NULL;
p->next = t;
p = p->next;
La = La->next;
}
else {
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = Lb->data;
t->next = NULL;
p->next = t;
p = p->next;
Lb = Lb->next;
}
}
if(La){    //La还没比较完
while(La){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = La->data;
t->next = NULL;
p->next = t;
p = p->next;
La = La->next;
}
}
else if(Lb){    //Lb还没比较完
while(Lb){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = Lb->data;
t->next = NULL;
p->next = t;
p = p->next;
Lb = Lb->next;
}
}
return head;
}

void print(LinkedList Lc)                       //输出链表中的结点
{
LinkedList p=Lc->next;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}

int main()
{
printf("已知两个非递减有序的单链表la和lb,将la和lb合并成一个线性表lc,lc也非递减有序。\n");
printf("1.创建单链表La\n");
LinkedList La = LinkedListCreat();
printf("2.创建单链表Lb\n");
LinkedList Lb = LinkedListCreat();
printf("3.顺序合并单链表\n");
LinkedList Lc = Union(La,Lb);
printf("合并成功!\n");
printf("4.输出合并后的链表\n");
print(Lc);
return 0;
}


/* 程序4
已知一个单链表,利用原表把单链表逆置。
设计要求:在程序中构造三个子程序分别为
LinkedList  LinkedListCreat( )                     //建立链表
void List_reverse(LinkedList L)                   //逆置链表
void print(LinkedList L);                         //输出链表中的结点
*/

#include <stdio.h>
#include <malloc.h>
/* 单链表的结点类型 */
typedef struct LNode{
int data;
LNode* next;
}LNode,*LinkedList;

LinkedList  LinkedListCreat( )                     //按顺序建立链表
{
LinkedList head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
printf("请输入链表大小:(最多1000个)\n");
int n,i,a[1001];
scanf("%d",&n);
printf("请输入链表的所有元素:\n");
for(i=1;i<=n;i++)    //输入元素
scanf("%d",&a[i]);
//尾插法创建链表
LinkedList p = head;
for(i=1;i<=n;i++){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = a[i];
t->next = NULL;
p->next = t;
p = t;
}
return head;
}

void List_reverse(LinkedList L)                   //逆置链表
{
LinkedList p = L->next;
int data[1001],i;
for(i=1;p;i++){
data[i] = p->data;
p = p->next;
}
p = L->next;
while(p){
p->data = data[--i];
p = p->next;
}
}

void print(LinkedList L)                       //输出链表中的结点
{
LinkedList p=L->next;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}

int main()
{
printf("已知一个单链表,利用原表把单链表逆置。\n");
printf("1.创建单链表L\n");
LinkedList L = LinkedListCreat();
printf("2.链表逆置\n");
List_reverse(L);
printf("逆置成功!\n");
printf("3.输出合并后的链表\n");
print(L);
return 0;
}


/* 程序5
在计算机上先输入一串正整数的序列。请编写一个程序,首先用链表存储该序列。
然后执行删除操作,即先从链表中找出最小的结点,删除它。
然后再在剩余的链表中,找出最小的结点,再删除之。直至表空为止。
设计要求:在程序中构造四个子程序分别为
LinkedList  LinkedListCreat( )                 //建立链表
int min(LinkedList head);                      //求链表中的最小结点
LinkedList del(LinkedList head, int num);   //删除结点
void print(LinkedList L);                      //输出链表中的结点
*/

#include <stdio.h>
#include <malloc.h>
/* 单链表的结点类型 */
typedef struct LNode{
int data;
LNode* next;
}LNode,*LinkedList;

LinkedList  LinkedListCreat( )                     //按顺序建立链表
{
LinkedList head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
printf("请输入链表大小:(最多1000个)\n");
int n,i,a[1001];
scanf("%d",&n);
printf("请输入链表的所有元素:\n");
for(i=1;i<=n;i++)    //输入元素
scanf("%d",&a[i]);
//尾插法创建链表
LinkedList p = head;
for(i=1;i<=n;i++){
LinkedList t =  (LNode*)malloc(sizeof(LNode));
t->data = a[i];
t->next = NULL;
p->next = t;
p = t;
}
return head;
}

int min(LinkedList head)     //求链表中的最小结点,返回其逻辑序号
{
head = head->next;
int min=1,val=head->data,num=1;
while(head){
if(head->data < val)    //如果 当前节点元素值 < 之前存储的最小值
min = num,val = head->data;
head = head->next;
num++;
}
return min;
}

LinkedList del(LinkedList head, int num)  //删除结点
{
int count = 0;
LinkedList p = head;
while(count+1!=num){    //找到要删除节点的前一个节点
p = p->next;
count++;
}
LinkedList t = (LNode*)malloc(sizeof(LNode));
t = p->next;    //存储要删除的节点
p->next = t->next;
free(t);    //释放该空间
return head;
}

void print(LinkedList L)                       //输出链表中的结点
{
LinkedList p=L->next;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}

int main()
{
printf("创建一个单链表,依次删除其中值最小的节点\n");
printf("1.创建单链表L\n");
LinkedList L = LinkedListCreat();
printf("2.依次删除链表中值最小的节点\n");
getchar();
printf("当前链表所有元素:\n");
print(L);
while(L->next){
printf("请按回车执行删除操作");
getchar();
L = del(L,min(L));    //删除当前值最小的元素
print(L);
}
printf("链表已空!\n");
return 0;
}


/* 程序6
利用单循环链表作为存储结构,实现实验二中的约瑟夫环问题。
设计要求:在程序中构造三个子程序分别为
CiLinkList  CiLinkListCreat( )              //建立不带头结点的单循环链表
void del(CiLinkList last, int N, int K)     //依次输出符合要求的结点
void print(CiLinkList L);                   //输出链表中的结点
*/
#include <stdio.h>
#include <malloc.h>
/* 循环链表的结点类型 */
typedef struct LNode{
int data;
LNode* next;
}LNode,*CiLinkList;

CiLinkList  CiLinkListCreat( )              //建立不带头结点的单循环链表
{
CiLinkList p0,p;
printf("请输入链表大小:(最多1000个)\n");
int n,i,e;
scanf("%d",&n);
printf("请输入循环链表的所有元素:\n");
for(i=1;i<=n;i++){    //输入元素
scanf("%d",&e);
CiLinkList t = (LNode*)malloc(sizeof(LNode));    //创建节点,与之前的相连
t->data = e;
t->next = NULL;
if(i==1)    //第一个节点
p0 = t,p = t;
else{
p->next = t;
p = p->next;
}
}
p->next = p0;    //首尾相连
return p0;
}
void del(CiLinkList last, int N, int K)     //依次输出符合要求的结点
{
int num = 0;
while(last!=last->next){    //直到循环链表为空
while(num+1!=K-1){    //找到要删除节点的上一个节点
last = last->next;
num++;
}
//删除节点
CiLinkList t = last->next;
last->next = t->next;
printf("%d ",t->data);
free(t);
last = last->next;    //跳到被删除节点的下一个节点,重新开始循环
num = 0;
}
printf("%d ",last->data);
printf("\n");
}
void print(CiLinkList L)                  //输出链表中的结点
{
CiLinkList p = L->next;
printf("%d ",L->data);    //输出第一个元素
while(p!=L){
printf("%d ",p->data);    //输出剩下的元素
p = p->next;
}
printf("\n");
}

int main()
{
CiLinkList L = CiLinkListCreat();    //创建循环链表
printf("符合要求的顺序应为:\n");
del(L, 10, 3) ;    //依次输出符合要求的结点
return 0;
}


/* 程序7
在双向链表上实现线性表的下列运算:
a)        建立 DLinkedList  creat()
b)        插入void  DlistInsert(DLinkedList L,int x,int i)
c)        删除void  DlistDelete(DLinkedList L,int i)
*/
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct LNode{
int data;
LNode* pre;
LNode* next;
} LNode,*DLinkedList;
DLinkedList  creat()
{
DLinkedList head = (LNode*)malloc(sizeof(LNode)),p = head;
head->next = NULL;
head->pre = NULL;
printf("请输入链表大小:(最多1000个)\n");
int n,i,e;
scanf("%d",&n);
if(n<=0 || n>1000){
printf("请输入正确的链表大小!\n");
head = NULL;
return head;
}
printf("请输入循环链表的所有元素:\n");
for(i=1;i<=n;i++){    //输入元素
scanf("%d",&e);
DLinkedList t = (LNode*)malloc(sizeof(LNode));    //创建节点
t->data = e;
t->next = NULL;
t->pre = p;
p->next = t;
p = p->next;
}
return head;
}
void  DlistInsert(DLinkedList L,int x,int i)
{
int num = 0;
while(num<i && L){
L = L->next;
num++;
}
if(!L){
printf("插入失败,您要插入的位置已超过链表长度!\n");
return ;
}
DLinkedList pre = L->pre;
DLinkedList t = (LNode*)malloc(sizeof(LNode));
t->data = x;
t->next = L;
t->pre = pre;
L->pre = t;
pre->next = t;
}
void  DlistDelete(DLinkedList L,int i)
{
int num = 0;
while(num<i && L){    //找到要删除的位置
L = L->next;
num++;
}
if(!L){
printf("删除失败,您要删除的位置已超过链表长度!\n");
return ;
}
DLinkedList pre = L->pre;
pre->next = L->next;
if(L->next!=NULL)
L->next->pre = pre;
free(L);
}

void print(DLinkedList L)                  //输出链表中的结点
{
L = L->next;
while(L){
printf("%d ",L->data);    //输出剩下的元素
L = L->next;
}
printf("\n");
}
int menu()
{
int in;
printf("[1] 创建双链表\n");
printf("[2] 插入元素\n");
printf("[3] 删除元素\n");
printf("[4] 输出链表\n");
printf("[0] 按任意键退出\n");
scanf("%d",&in);
return in;
}
DLinkedList work(DLinkedList head ,int in)
{
switch(in){
case 1:
head = creat();
break;
case 2:
if(head==NULL){
printf("请先创建双链表!\n");
break;
}
int i,x;
printf("你要在第几个位置插入元素?\n");
scanf("%d",&i);
printf("你要插入的元素值是?\n");
scanf("%d",&x);
DlistInsert(head,x,i);
printf("当前链表:\n");
print(head);
break;
case 3:
if(head==NULL){
printf("请先创建双链表!\n");
break;
}
int n;
printf("你要删除第几个节点?\n");
scanf("%d",&n);
DlistDelete(head,n);
printf("当前链表:\n");
print(head);
break;
case 4:
if(head==NULL){
printf("请先创建双链表!\n");
break;
}
printf("当前链表:\n");
print(head);
break;
default:
exit(1);
}
system("pause");
system("cls");
return head;
}
int main()
{
DLinkedList head = NULL;
while(1){
int in;
in = menu();
head = work(head,in);
}
return 0;
}


/* 程序8
设有一个双链表,每个结点中除有prior,next及data〔可设为正整数〕三个域之外,还有一个专门记录访问该结点次数的数据域freq,其值在初始化时为零。
每当在链表中进行一次Search〔l,key〕时,则数据域data之值等于key的结点,其freq域之值将加一。
并使该双链表中结点按freq之值的递减顺序排列,freq值越大的结点越靠近表头。
请编写符合上述要求的Search〔l,key〕程序。
设计要求:在程序中构造三个子程序分别为
DLinkedList Creat()                          //建立链表
void Search(DLinkedList head,int key)    //查找链表中符合要求的结点
void print(DLinkedList head);              //输出链表中的结点
*/

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct LNode{
int data;
int freq;    //访问次数
LNode* prior;
LNode* next;
} LNode,*DLinkedList;

DLinkedList  creat()
{
DLinkedList head = (LNode*)malloc(sizeof(LNode)),p = head;
head->data = 0;
head->next = NULL;
head->prior = NULL;
head->freq = 0;
printf("请输入链表大小:(最多1000个)\n");
int n,i,e;
scanf("%d",&n);
if(n<=0 || n>1000){
printf("请输入正确的链表大小!\n");
head = NULL;
return head;
}
printf("请输入循环链表的所有元素:\n");
for(i=1;i<=n;i++){    //输入元素
scanf("%d",&e);
DLinkedList t = (LNode*)malloc(sizeof(LNode));    //创建节点
t->data = e;
t->next = NULL;
t->prior = p;
t->freq = 0;
p->next = t;
p = p->next;
}
return head;
}
void Search(DLinkedList head,int key)    //查找链表中符合要求的结点
{
DLinkedList p = head->next;
head = head->next;
while(head){    //找到符合要求的节点
if(head->data == key){
head->freq++;
break;
}
head = head->next;
}
while(p){
if(head->freq >= p->freq){
int t;
t = head->data;head->data = p->data;p->data = t;
t = head->freq;head->freq = p->freq;p->freq = t;
break;
}
p = p->next;
}
}

void print(DLinkedList L)                  //输出链表中的结点
{
DLinkedList p = L->next;
L = L->next;
while(L){
printf("%d ",L->data);    //输出剩下的元素
L = L->next;
}
printf("\n");
while(p){
printf("%d ",p->freq);    //输出剩下的元素
p = p->next;
}
printf("\n");
}
int menu()
{
int in;
printf("[1] 创建双链表\n");
printf("[2] 查找链表中符合要求的节点\n");
printf("[3] 输出链表\n");
printf("[0] 按任意键退出\n");
scanf("%d",&in);
return in;
}
DLinkedList work(DLinkedList head ,int in)
{
switch(in){
case 1:
head = creat();
break;
case 2:
if(head==NULL){
printf("请先创建双链表!\n");
break;
}
int key;
printf("请问你要查找的关键值(key)是?\n");
scanf("%d",&key);
Search(head,key);
printf("查找结果:\n");
print(head);
break;
case 3:
if(head==NULL){
printf("请先创建双链表!\n");
break;
}
printf("当前链表:\n");
print(head);
break;
default:
exit(1);
}
system("pause");
system("cls");
return head;
}
int main()
{
DLinkedList head = NULL;
while(1){
int in;
in = menu();
head = work(head,in);
}
return 0;
}


Freecode : www.cnblogs.com/yym2013
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: