算法设计学习5
实验目的及要求:
目标是使学生学会分析数据对象的特点,掌握数据组织的方法和在计算机中的存储方式,能够对具体问题中所涉及的数据选择合适的逻辑结构、存储结构,进而在此基础上,对各种具体操作设计高效的算法,培养良好的程序设计技能。
实验设备环境:
1.微型计算机
2.DEV C++(或其他编译软件)
实验步骤:
任务一:
设头指针为 head,并设带头结点单链表中的元素递增有序,编写算法,将元素 x 插入带头结点单链表的适当位置上。要求: 插入后保持单链表元素的递增有序。
[算法思想] 从单链表的第一个元素结点开始,将元素 x 与每个结点的 data 域逐个进行比较。当 data 域的值小于等于元素 x 的值时,进行下一个结点的比较;否则就找到了插入结点的合适位置,此时申请新结点把元素 存入 data 域,然后把新结点插入; 如果比较到最后一个结点,仍有 data 域的值小于等于元素 x 的值,则把新结点插入单链表尾。
代码如下:
#include<stdio.h>
#include<malloc.h>
typedef int DataType;
#include"LinList.h"
void LinListInsert(SLNode *head,DataType x){
SLNode *curr,*pre,*q;
curr=head->next;
pre=head;
while(curr!=NULL&&curr->data<=x){
pre=curr;
curr=curr->next;
}
q=(SLNode*)malloc(sizeof(SLNode));
q->data=x;
q->next=pre->next;
pre->next=q;
}
int main(void){
SLNode *head;
int i,x,a;
ListInitiate(&head);//初始化
printf("请输入递增有序的元素:\n");
for(i=0;i<10;i++){//插入元素
scanf("%d",&a);
ListInsert(head,i,a);
}
printf("请输入要插入的元素:\n");
scanf("%d",&x);
LinListInsert(head,x);
printf("插入后的链表元素:\n");
for(i=0;i<ListLength(head);i++){
ListGet(head,i,&x);
printf("%d ",x);
}
Destroy(&head);
}
头文件:
typedef struct Node{
DataType data;
struct Node *next;
}SLNode;
void ListInitiate(SLNode**head){
*head=(SLNode *)malloc(sizeof(SLNode));
(*head)->next=NULL;
}
int ListLength(SLNode *head){
SLNode *p=head;
int size=0;
while(p->next!=NULL){
p=p->next;
size++;
}
return size;
}
int ListInsert(SLNode *head,int i,DataType x){
SLNode *p,*q;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<i-1){
p=p->next;
j++;
}
if(j!=i-1){
printf("插入元素位置参数错!");
return 0;
}
q=(SLNode *)malloc(sizeof(SLNode));
q->data=x;
q->next=p->next;
p->next=q;
return 1;
}
int ListDelete(SLNode *head,int i,DataType *x){
SLNode *p,*s;
int j;
p=head;
j=-1;
while(p->next!=NULL&&p->next->next!=NULL&&j<i-1){
p=p->next;
j++;
}
if(j!=i-1){
printf("删除元素位置参数错!");
return 0;
}
s=p->next;
*x=s->data;
p->next=p->next->next;
free(s);
return 1;
}
int ListGet(SLNode *head,int i,DataType *x){
SLNode *p;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<i){
p=p->next;
j++;
}
if(j!=i){
printf("取出元素位置参数错!");
return 0;
}
*x=p->data;
return 1;
}
void Destroy(SLNode **head){
SLNode *p,*p1;
p=*head;
while(p!=NULL){
p1=p;
p=p->next;
free(p1);
}
*head=NULL;
}
任务二:
设 head 为单链表的头指针,并设单链表带有头结点,编写算法,将单链表中的元素按照元素的值递增有序地进行就地排序。[说明] 就地排序是指在不增加新结点的基础上,通过修改原有单链表的指针域来达到排序的目的。
[算法思想] 在例 2-6 算法的基础上再增加一重循环,即可实现全部元素的排序。因为此时的排序过程没有申请新的结点空间,所以这样的排序算法满足就地排序,即不增加新的内存空间的设计要求。
具体实现过程是: 把头指针 head 所指单链表置空(即初始时 head 所指单链表仅包含一个头结点), 把去掉头结点的原单链表(设由指针 p 指示)中的元素逐个重新插入 head 所指单链表中每次插入都从 head 所指单链表的第一个元素结点开始,逐个比较 head 所指单链表每个结点的 data 域和 p 所指单链表的当前第一个元素结点的 data 域,当前者小于或等于后者时,用 head 所指单链表的下一个结点进行比较;否则就找到了插入结点的合适位置,从 p 所指单链表中取下当前第一个元素结点插入 head 所指单链表的合适位置。这样的过程一直进行到 p 所指单链表为空时结束
代码如下:
#include<stdio.h>
#include<malloc.h>
typedef int DataType;
#include"LinList.h"
void LinListSort(SLNode *head){
SLNode *curr,*pre,*p,*q;
p=head->next;
head->next=NULL;
while(p!=NULL){
curr=head->next;
pre=head;
while(curr!=NULL&&curr->data<=p->data){
pre=curr;
curr=curr->next;
}
q=p;
p=p->next;
q->next=pre->next;
pre->next=q;
}
}
int main(void){
SLNode *head;
int i,x,a;
ListInitiate(&head);
printf("请输入链表中的元素:\n");
for(i=0;i<10;i++){
scanf("%d",&a);
ListInsert(head,i,a);
}
LinListSort(head);
printf("排序后链表中的元素:\n");
for(i=0;i<ListLength(head);i++){
ListGet(head,i,&x);
printf("%d ",x);
}
Destroy(&head);
}
头文件:
typedef struct Node{
DataType data;
struct Node *next;
}SLNode;
void ListInitiate(SLNode**head){
*head=(SLNode *)malloc(sizeof(SLNode));
(*head)->next=NULL;
}
int ListLength(SLNode *head){
SLNode *p=head;
int size=0;
while(p->next!=NULL){
p=p->next;
size++;
}
return size;
}
int ListInsert(SLNode *head,int i,DataType x){
SLNode *p,*q;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<i-1){
p=p->next;
j++;
}
if(j!=i-1){
printf("插入元素位置参数错!");
return 0;
}
q=(SLNode *)malloc(sizeof(SLNode));
q->data=x;
q->next=p->next;
p->next=q;
return 1;
}
int ListDelete(SLNode *head,int i,DataType *x){
SLNode *p,*s;
int j;
p=head;
j=-1;
while(p->next!=NULL&&p->next->next!=NULL&&j<i-1){
p=p->next;
j++;
}
if(j!=i-1){
printf("删除元素位置参数错!");
return 0;
}
s=p->next;
*x=s->data;
p->next=p->next->next;
free(s);
return 1;
}
int ListGet(SLNode *head,int i,DataType *x){
SLNode *p;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<i){
p=p->next;
j++;
}
if(j!=i){
printf("取出元素位置参数错!");
return 0;
}
*x=p->data;
return 1;
}
void Destroy(SLNode **head){
SLNode *p,*p1;
p=*head;
while(p!=NULL){
p1=p;
p=p->next;
free(p1);
}
*head=NULL;
}