一、抄写自己所选择的题目。
1、已知一顺序表A,其元素非递减有序排列,编写一个算法,删除顺序表中值相同多余的元素(相同值保留一个)。
2、已知带头结点的单链表L中的节点是按整数值递增排序的,试写一算法,将值为x的节点插入到表L中,使得表L仍然有序。
分析算法的时间复杂度。
二、写出算法设计思路。
1.建立一个顺序表用于存储一组非递减排序的整形数据,对顺序表中的每个元素与其下一个元素进行比较操作。
用指针记录当前所比较的元素,如果相等则对当前指针所指向的元素进行删除操作,并将它后面的数据前移,再与下一个元素比较,如果还相等就继续删除操作,否则指向下个元素,再比较直至无重复的元素。
2. 建立一个带头节点的单链表,其节点按整数值递增排序。
创建一个新的节点,并由键盘输入节点的值。
将其与链表中原有的节点(头节点不参与比较)按顺序作比较,并用指针指向当前的位置,若不大于当前节点,则在当前位置这前作插入操作,否则在最后作插入操作。
三、编写代码,调试运行,实现题目要求(提示:考虑到插入和删除的位置是否超出范围等可能出现的异常问题)。
解1.法I:
#include "stdio.h"
#include "conio.h"
#define SIZE 10
main()
{ int SqList_A[SIZE]={23,3,45,65,23,44,5,7,89,0};
int i,j,n,m,l=SIZE;
for(i=0;i<l;i++) printf("%d ",*(SqList_A+i));
printf("\nThe new one is:\n");
for(i=0;i<(l-1);i++)
for(j=0;j<(l-1);j++)
if(SqList_A[i]==SqList_A[j])
if(i!=j)
{n=i;m=i+1;
for(;m<l;n++,m++)
SqList_A[n]=SqList_A[m];
l=l-1; }
for(i=0;i<l;i++) printf("%d ",*(SqList_A+i)); printf("\n\n");
getch();
}
法II:
#include "stdio.h"
#include "conio.h"
#define SIZE 18
#define ERROR 0
#define OK 1
int length; /* 定义宏观变量*/
typedef int status;
typedef struct{
int *elem;
int length;
int listsize;} SqList;
status ListDelete(SqList *L)
{ /*删除顺序表L中值相同多余的元素(相同值保留一个)*/
int i=0,j,n=0;
SqList *p=L;
if(!p) return ERROR;
while(i<p->length)
{if(*(p->elem+i)==*(p->elem+i+1))
{/*删除相同多余的元素*/
for(j=i;j<p->length;j++) *(p->elem+j)=*(p->elem+j+1);
n++;
p->length--;}
if(!(*(p->elem+i)==*(p->elem+i+1)))
/*判断第i个数是否任和下一个数相同*/
i++;}
length=SIZE-n;
return n;}
main()
{int a[SIZE]={1,2,2,5,6,7,7,12,13,13,13,18,19,20,21,24,24,39},t; int n,m;
SqList A;
A.elem=a;
for(n=0;n<SIZE;n++)
printf("%d ",a[n]);
A.length=A.listsize=SIZE;
t=ListDelete(&A) ;
if(!t)printf("ListDelete ERROR!\n");
else
{
printf("\nThe new one is:\n");
for(n=0;n<length;n++)
printf("%d ",a[n]);}
getch();
}
解2.
#include "stdio.h"
#include "conio.h"
#define SIZE 10
#define ERROR 0
#define NULL 0
#define OK 1
int a[SIZE]={1,3,5,8,10,12,14,17,19,26},i;
typedef int status;
typedef struct nod{
int data;
struct nod *next;} node;
status CreatList(node *L)
{/*建立一个带头结点的节点按整数值递增排序的单链表L*/
node *p,*h=NULL;
h=p=(node *)malloc(sizeof(node));
if(!p) return ERROR; /*节点创建失败*/
p->data=a[i];
for(i=1;i<SIZE;i++) /*创建整数值递增排序链表*/
{p->next=(node *)malloc(sizeof(node));
p=p->next;
p->data=a[i];}
p->next=NULL;
L->next=h;
return OK;}
status ListInsert(node *L,int x)
{int i,k;
for(i=0;i<SIZE;i++) if(x>=a[i]&&x<a[i+1]) k=i+1;
{for(i=SIZE-1;i>=k;i--) a[i+1]=a[i]; a[k]=x;} }
main()
{node *L,*p;
int t,x,i,k;
printf("Please input the number you want to insert x:\n"); scanf("%d",&x);
printf("The List is:\n");
for(i=0;i<SIZE;i++)
printf("%d ",a[i]);
printf("\nAfter inert,the new one is:\n");
L=(node *)malloc(sizeof(node));
if(!L){ printf("ERROR!\n");return;}
t=CreatList(L); /*创建链表*/
if(!t){ printf("ERROR!\n");return;}
ListInsert(L,x);
for(i=0;i<SIZE+1;i++)
printf("%d ",a[i]);
getch();
}
时间复杂度为:O(n)
四、写出算法设计、编程和调试运行的体会。
经过上学期对C语言半年的学习可以说掌握的基本可以,但是三天不上手就会手生。
现在再次运用时尽忘记了许多,甚至不知如何下手,只得再次翻阅C语言的课本。
不过通过这次实验的复习,我在学习数据结构的同时也对C语言进行了一次复习回顾,收获颇丰。
但是也不乏出现一些问题,比如:
1.如何在调用函数中返回两个以上的返回值?
2.头结点如何体现,怎样体现它的作用?希望老师可以帮助解决这些问题,谢谢!。