c语言之链表编程

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2.1 试描述头指针、头结点、开始结点的区别,并说明头指针和头结点的作用。

头指针:存放链表首地址的指针变量。头结点:链表的开始结点之前的一个同类型结点。开始结点:链表的第一个元素所在的结点。

头指针的作用:用于确定链表的地址。头结点的作用:方便于处理开始结点的操作和处理其它结点的操作保持一致,也方便于处理空表的操作和处理非空表的操作保持一致。

2.2 有哪些链表可由一个尾指针来唯一确定?即从尾指针出发能访问链表上任何一个结点。单循环链表,双链表,双循环链表

2.3 设线性表存放在向量A[arrsize]的前elenum个分量中,且递增有序。试写一算法,将x 插入到线性表的适当位置上,以保持线性表的有序性。并且分析算法的时间复杂度。

#define arrsize 100

int InsertOrder(int A[], int elenum, int x)

{ int i=elenum-1;

if (elenum==arrsize) //在顺序表上进行插入操作必须先判满

{ printf(“full”);

return 0;

}

while (i>=0&&A[i]>x)

{ A[i+1]=A[i];

i--;

} //从后往前进行比较,比较的同时完成移动

A[i+1]=x;

elenum++;

return elenum; //返回变化之后的表长

} //本题也可以先进行比较,比较的结果就是找到了插入的合适位置,然后再完成插入操作。但这样做比较耗时。

假设n=elenum,则时间复杂度:最坏O(n),最好O(1),平均O(n)

2.4 用向量作存储结构,试设计一个算法,仅用一个辅助结点,实现将线性表中的结点循环右移k位的运算,并且分析算法的时间复杂度。

void MoveKList(int a[],int n,int k)

{ int i, j, temp;

for (i=1; i<=k; i++) //外层for循环控制循环右移的次数i

{ temp=a[n-1]; //把表尾元素保存到辅助结点变量temp中

for (j=n-2; j>=0; j--)

a[j+1]=a[j]; //内层for循环完成一次整体右移一位

a[0]=temp; //把原来的表尾元素移至表头

}

}

时间复杂度T(n) = k*n = O(n)

2.5 已知带头结点的动态单链表L中的结点是按整数值递增排列的,试写一算法将值为x的结点插入表L中,使L仍然有序。

typedef int datatype;

typedef struct node

{ datatype data;

struct node *next;

} linklist; //linklist结构体类型描述

void InsertListOrder(linklist *L, datetype x)

{ linklist *p=L; //对寻位指针p初始化

linklist *s=(linklist *)malloc(sizeof(linklist)); //使用强制类型转换将新结点的地址赋给指针s s->data=x;

while((p->next)&&(p->next->data

p=p->next; //后移寻位指针

s->next=p->next;

p->next=s;

} //本题也可以采用两个寻位指针p和q,让q始终跟随p的后移而后移。

2.6 设计一算法,逆置带头结点的动态单链表L。

typedef int datatype;

typedef struct node

{ datatype data;

struct node *next;

} linklist;

void Reverse(linklist *L)

{ linklist *p,*q;

p=L->next;

q=L->next;

L->next=NULL;

while(q)

{ q=q->next;

p->next=L->next;

L->next=p;

p=q;

}

} //用指针q遍历结点,指针p跟随指针q,使用头插法把当前结点*p插入到修改之后的单链表中。

2.7 试编写在带头结点的动态单链表和静态单链表上实现线性表操作Length(L)的算法,并将长度写入头结点的数据域中。

(1) typedef int datatype;

typedef struct node

{ datatype data;

struct node *next;

} linklist;

void Length1(linklist *L)

{ linklist *p=L-next;

int i=0;

while(p)

{ i++;

p=p->next;

}

L->data=i; //按照题目要求,将表长写入头结点的数据域中。

}

(2) #define maxsize 1024

typedef int datatype;

typedef struct

{ datatype data;

int next;

} node;

node nodepool[maxsize];

void Length2(int L)

{ int i=0, p=nodepool[L].next;

while(p)

{ i++;

p=nodepool[p].next;

}

nodepool[L].data=i;

}

2.8 假设有两个按元素值递增有序排列的线性表A和B,均以单链表①作存储结构,试编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许值相同)排列的线性表C,并要求利用原表(即A表和B表)的结点空间存放表C。①今后若不特别指明,链表均是指动态链表,且可以带头结点。

typedef int datatype;

typedef struct node

{ datatype data;

struct node *next;

} linklist;

linklist *Connect ( linklist *A, linklist *B )

{ linklist *C, *p, *q, *r;

C=A; //C为最后返回的链表头指针

p=A->next; //p总是指向链表A中当前正在比较的结点

q=B->next; //q总是指向链表B中当前正在比较的结点

C->next=NULL; //置空链表C

while(p&&q) //当链表A和链表B中还有没比较的结点时

{ if (p->datadata)

{ r=p; p=p->next; }

else

{ r=q; q=q->next; } //r总是指向*p和*q二者中数据较小的结点

r->next=C->next;

C->next=r; //将*r按照头插法插入到链表C中

相关文档
最新文档