为了更好地学习数据结构,方便自己复习反思,特建立此分类进行课后习题的总结,通过总结来督促自己学习与反思,提升水平,一步步找出更好的算法。
1.将一元素插入一个有序的顺序表中,使其仍然有序,写出能够实现此算法的代码。
我的思路是将元素先插入表尾,之后再进行插入排序,代码如下:
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;
typedef struct
{
elemtype data[maxsize];
int length;
}sqlist;
status visit(elemtype c)
{
printf("%d ",c);
return OK;
}
status initlist(sqlist *l)
{
l->length=0;
return OK;
}
status insertlist(sqlist *l,elemtype e,int i)
{
int k;
if(l->length==maxsize)
return ERROR;
if(i<1||i>l->length+1)
return ERROR;
if(i<=l->length)
for(k=l->length-1;k>=i-1;k--)
l->data[k+1]=l->data[k];
l->data[i-1]=e;
l->length++;
return OK;
}
status listtraverse(sqlist l)
{
int i;
for(i=0;ilength;i++)
{
visit(l.data[i]);
}
putchar('\n');
return OK;
}
status insertsort(sqlist *l){
int i,j,temp;
for(i=1;ilength;i++){
if(l->data[i]data[i-1]){
temp=l->data[i];
for(j=i-1;j>=0&&l->data[j]>temp;j--){
l->data[j+1]=l->data[j];
}
l->data[j+1]=temp;
}
}
}
int main(void){
sqlist L;
int i=0;
initlist(&L);
for(i=0;i<10;i++){
insertlist(&L,i,i);
}
listtraverse(L);
int insert=5;
insertlist(&L,insert,L.length+1);
listtraverse(L);
insertsort(&L);
listtraverse(L);
}
2.删除一个顺序表中的重复元素
我的思路是使用i,j两个索引,其中i从0开始,j从i+1开始,遍历整个顺序表,当有两元素相等时,删除其中一个即可。
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;
typedef struct
{
elemtype data[maxsize];
int length;
}sqlist;
status visit(elemtype c)
{
printf("%d ",c);
return OK;
}
status initlist(sqlist *l)
{
l->length=0;
return OK;
}
status insertlist(sqlist *l,elemtype e,int i)
{
int k;
if(l->length==maxsize)
return ERROR;
if(i<1||i>l->length+1)
return ERROR;
if(i<=l->length)
for(k=l->length-1;k>=i-1;k--)
l->data[k+1]=l->data[k];
l->data[i-1]=e;
l->length++;
return OK;
}
status listtraverse(sqlist l)
{
int i;
for(i=0;ilength;i++)
{
visit(l.data[i]);
}
putchar('\n');
return OK;
}
status deleteelem(sqlist *l,elemtype e,int i)
{
int k;
if(l->length==0)
return ERROR;
if(i<1||i>l->length)
return ERROR;
e=l->data[i-1];
if(ilength)
{
for(k=i;klength-1;k++)//只需要让后面的不包括自身的元素向前
l->data[k]=l->data[k+1];
}
l->length--;
return OK;
}
status deletesameelem(sqlist *l){
int i,j;
elemtype e;
for(i=0;ilength;i++){
for(j=i+1;jlength;j++){
if(l->data[i]==l->data[j]){
deleteelem(l,e,j);
}
}
}
}
int main(void){
sqlist L;
int i=0;
initlist(&L);
for(i=0;i<10;i++){
insertlist(&L,i,i);
}
listtraverse(L);
int insert=5;
insertlist(&L,insert,L.length+1);
listtraverse(L);
deletesameelem(&L);
listtraverse(L);
}
3.删除指定范围内的所有元素
最开始我的思路是遍历表,将所有在指定范围的元素找出来并删除,但在实现过程中出现了一些问题,只删除了奇数项而偶数项依然存在。之后我参考了另一个算法,从反面入手,增加新索引k=0,使不在范围内的元素保存在原顺序表中,同时k++,最后让表长等于k即可,代码如下:
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;
typedef struct
{
elemtype data[maxsize];
int length;
}sqlist;
status visit(elemtype c)
{
printf("%d ",c);
return OK;
}
status initlist(sqlist *l)
{
l->length=0;
return OK;
}
status insertlist(sqlist *l,elemtype e,int i)
{
int k;
if(l->length==maxsize)
return ERROR;
if(i<1||i>l->length+1)
return ERROR;
if(i<=l->length)
for(k=l->length-1;k>=i-1;k--)
l->data[k+1]=l->data[k];
l->data[i-1]=e;
l->length++;
return OK;
}
status listtraverse(sqlist l)
{
int i;
for(i=0;ilength;i++)
{
visit(l.data[i]);
}
putchar('\n');
return OK;
}
status deleteelem(sqlist *l,int i)
{
int k;
if(l->length==0)
return ERROR;
if(i<1||i>l->length)
return ERROR;
if(ilength)
{
for(k=i;klength-1;k++)//只需要让后面的不包括自身的元素向前
l->data[k]=l->data[k+1];
}
l->length--;
return OK;
}
status deleteeleminrange(sqlist *l,int x,int y){
int i=0,k=0;/*这一步一定要将k初始化为0否则会出现整个线性表全为同一数字的情况*/
for(i=0;ilength;i++){
if(l->data[i]<x||l->data[i]>y){
l->data[k++]=l->data[i];
}
}
l->length=k;
}
int main(void){
sqlist L;
int i=0,x=0,y=0;
initlist(&L);
for(i=0;i<10;i++){
insertlist(&L,i,i);
}
listtraverse(L);
deleteeleminrange(&L,2,6);
listtraverse(L);
}
4.给定一个含有数字,字母,其他字符的线性表,要求按照字母,数字,其他字符的顺序进行排序。
对于此题,我的思路是使用ctype.h头文件中的isdigit(),isalpha()函数,对线性表进行遍历,找出其中的数字字母其他字符。之后转存到另一线性表中即可,代码如下:
#include
#include
#include
#define maxsize 20
typedef int status;
typedef char elemtype;
typedef struct sqlist{
elemtype ch[maxsize];
int length;
}sqlist;
status initlist(sqlist *l){
l->length=0;
}
status createlist(sqlist *l){
l->ch[0]='a';
l->length++;
l->ch[1]=',';
l->length++;
l->ch[2]='2';
l->length++;
}
status visit(elemtype c){
printf("%c ",c);
}
status traverselist(sqlist l){
for(int i=0;ilength;i++){
visit(l.ch[i]);
}
printf("\n");
}
elemtype getelem(sqlist *l,int i){
elemtype e;
if(l->length==0)
return 0;
e=l->ch[i-1];
return e;
}
int main(void){
sqlist l,l2;
elemtype e;
int i,k=0;
initlist(&l);
initlist(&l2);
l.ch[0]='a';
l.length++;
l.ch[1]=',';
l.length++;
l.ch[2]='2';
l.length++;
l.ch[3]='f';
l.length++;
l.ch[4]='.';
l.length++;
l.ch[5]='5';
l.length++;
traverselist(l);
for(i=1;i<=l.length;i++){
e=getelem(&l,i);
if(isalpha(e)){
l2.ch[k++]=e;
l2.length++;
}
}
for(i=1;ilength+1;i++){
e=getelem(&l,i);
if(isdigit(e)){
l2.ch[k++]=e;
l2.length++;
}
}
for(i=1;ilength+1;i++){
e=getelem(&l,i);
if(!isalpha(e)&&!isdigit(e)){
l2.ch[k++]=e;
l2.length++;
}
}
traverselist(l2);
}
5.给定一顺序表,将其对称反转
例如:将{0 1 2 3 4 5 6 7 8 9}反转为{5 6 7 8 9 0 1 2 3 4}
我的思路是:用两个索引i=0,j=m(m为对称轴位置)对表进行遍历,遍历的同时左右进行交换,代码如下:
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;
typedef struct
{
elemtype data[maxsize];
int length;
}sqlist;
status visit(elemtype c)
{
printf("%d ",c);
return OK;
}
status initlist(sqlist *l)
{
l->length=0;
return OK;
}
status insertlist(sqlist *l,elemtype e,int i)
{
int k;
if(l->length==maxsize)
return ERROR;
if(i<1||i>l->length+1)
return ERROR;
if(i<=l->length)
for(k=l->length-1;k>=i-1;k--)
l->data[k+1]=l->data[k];
l->data[i-1]=e;
l->length++;
return OK;
}
status listtraverse(sqlist l)
{
int i;
for(i=0;ilength;i++)
{
visit(l.data[i]);
}
putchar('\n');
return OK;
}
status changeorder(sqlist *l,int m,int n){/*m为对称轴位置,n为表长*/
int temp;
int i=0,j=m;
while(i!=m&&j!=n){
temp=l->data[i];
l->data[i]=l->data[j];
l->data[j]=temp;
i++;
j++;
}
}
int main(void){
sqlist L,l;
int i;
initlist(&L);
for(i=0;i<10;i++){
insertlist(&L,i,L.length+1);
}
listtraverse(L);
changeorder(&L,5,10);
listtraverse(L);
}
以上是我所想到的一些解决问题的方法,今后还会不断反思,设计出更为高效的算法。