typedef struct Node {
ElemType data;
struct Node *next;
} Node,*Linklist;
LinkLIst L;
LinkList 与 Node*同为结构指针类斜体样式型,这两种类型是等价的。
通常我们习惯上用LinkList说明指针变量,强调它是某个单链表的头指针变量,用
Node*来定义指向单链表中节点的指针。
int listlength(linklist L){
node *p;
p=->next;
j=0;
while(p!=NULL){
p=p->next;
j++;
}
return j;
}
InitList(linklist *L){
L=(linklist*)malloc(sizeof(node));
L->next=NULL;
}
linklist creatfromhead(linklist l){
node *s;
char c;
int flag=1;
while(flag){
c=getchar();
if(c!='$'){
s(node*)malloc(sizeof(node))
s->data=c;
s->next=L->next;
L->next=s;
}
else flag=0;
}
}
linklist createfromtail(linklist L){
linklist L;
node *r,*s;
char c;
int flag=1;
r=L;
while(flag){
c=getchar();
if(c!='$'){
s=(node*)malloc(sizeof(node));
s->data=c;
r->next=s;
r=s;
}
else{
flag=0;
r->next=NULL;
}
}
}
node *get(linklist L,int i)
{
int j=0;
node *p;
p=L;
while((p->next!=NULL)&&(j<i)){
p=p->next;
j++;
}
if(i==j)return p;
else return NULL;
}
node *locate(linklist l,elemtype key)
{
node *p;
p=l->next;
while(p!=NULL){
if(p->data!=key)
p=p->next;
else break;
}
return p;
}
void inslist(linklist L,int i,elemtype e){
node *pre,*s;
int k=0;
pre=L;
while(pre!=NULL&&k<(i-1))
{
pre=pre->next;
k++;
}
if(!pre)
{
printf("插入位置不合理");
return ERROR;
}
s=(node*)malloc(sizeof(node));
s->data=e;
s->next=pre->next;
pre->next=s;
return OK;
}
void dellist(linklist L,int i,elemtype *e)
{
node *p,*r;
int k=0;
p=L;
while(p->next!=NULL&&k<(i-1))
{
p=p->next;
k++;
}
if(k!=i-1)
{
printf("删除位置i不合理");
return error;
}
r=p->next;
p->next=p->next->next;
*e=r->data;
free(r);
}
void difference(linklist la,linklist lb) {
node *pre,*p,*q,*r;
pre=la;
p=la->next;
while(p!=NULL) {
q=lb->next;
while(q!=NULL&&q->data!=p->data) {
q=q>next;
}
if(q!=NULL) {
r=p;
pre->next=p->next;
p=p->next;
free(r);
} else {
pre=p;
p=p->next;
}
}
}
【问题分析】逆置就是使得表中内容由原来的(a1,a2,…,ai-1,ai,ai+1, …,an)变为 (an,an-1,…,ai+1,ai,ai-1, …,a1)。就地逆置就是不需要额外申请结点空间,只需要 利用原有的表中的节点空间。若对顺序表中的元素进行逆置,可以借助于“交换”前后相应 元素;对单链表中的元素进行逆置,则不能按“交换”思路,因为对于链表中第 i 个结点需 要顺链查找第 n-i+1(链表长度为 n)个结点,逆置链表的时间复杂度将达 O(n2)。
【算法思路】用头插法完成
- 【初始化】逆置链表L初始为空表,指针p指向原表当前处理结点
- 【头插法】依次取原链表中当前结点p
将其作为第一个结点插入到逆置链表L的表头L
q为保存原链表当前结点的下一个处理位置
【算法描述】
void reverselist(linklist l)
{
p=l->next;
l->next=NULL;
while(p!=NULL){
q=p->next;
p->next=l->next;
l->next=p;
p=q;
}
}
建立一个带头结点的线性链表,用以存放输入的二进制数,链表中每个结点的
data 域存放一个二进制位。并在此链表上实现对二进制数加 1 的运算
【问题分析】
①建链表:带二进制数可用带头结点的单链表存储,第一个结点存储二进制数的最高位,依次存储,最后一个结点存储二进制数的最低位。
②二进制加法规则:实现二进制数加 1 运算,方向从低位往高位找到第一个值为 0 的位,把该位改成1,其后所有各位改成0
③链表实现二进制加 1 时,从高位往低位与运算方向正好相反,从第一个结点开始找,找出最后一个值域为 0 的结点,把该结点值域赋为 1,其后所有结点的值域赋为 0。
④若在链表中未找到值域为 0 的结点,则表示该二进制数各位均为 1,此时,申请一新结点,值域为 1,插入到头结点与原链表的第一个结点之间,成为新链表的第一个结点,其后所有结点的值域赋为 0。
【算法描述】
void binadd(linklist l) {
node *q,*r,*s;
q=l->next;
r=l;
while(q!=NULL)
{
if(q->data==0) r=q;
q=q->nest;
}
if(r!=l)
{
r->data=1;
} else
{
s=(node*)malloc(sizeof(node));
s->data=1;
s->next=l->nest;
l->nest=s;
r=s;
}
r=r->nest;
while(r!=NULL)
{
r->data=0;
r=r->nest;
}
}