一步一步学习数据结构(2)-链表及其操作

(1)单链表的节点插入操作

     假设p指向一个节点,要将s所指节点插入p所指节点之后的操作如下:

      s->next=p->next;

      p->next=s;

(2)单链表的节点删除操作

节点a,节点b......假设p为指向a的指针,只需要将p的指针域next指向原来p的下一个节点的下一个节点即可。即:

(注意释放所删除节点的内存空间)

q=p->next;  

p->next=p->next->next;

Free(q);//调用free函数来释放q所指节点的内存空间

 (3)尾插法建立单链表的算法

假设有n个元素已经存储在数组a中,用尾插法建立链表C

void CreatelistR(LNode *&C,int a[],int n){                   //要改变的变量用引用型

LNode *s*r;                 //s用来指向新申请的节点,r始终指向c的终端节点

int i

C=LNode *mallocsizeofLNode));//申请C的头节点空间

C->next=NULL;

r=C;             //r指向头节点,因为此时头节点就是终端结点

for(i=1i<=n;++i){//循环申请n个节点来接受数组a中的元素

s=(LNode *)malloc(sizeof(LNode));//s指向新申请的结点

s->data=a[i];//用新申请的节点来接受a中的元素

r->next=s;//r来接纳新结点

r=r->next;

}

r->next=Null;

}

(4)头插法建立单链表的算法

 void CreatelistR(LNode *&C,int a[],int n){  

LNode *s

int i

C=LNode*mallocsizeofLNode));

C->next=NULL

for(i=1;i<=n;++i){

s=(LNode*)malloc(sizeof(LNode));

s->data=a[i];

/*下面两句是头插法的关键步骤*/

s->next=C->next;//s所指新节点的指针域next指向C中的开始节点

C->next=s

}

}

(5)单链表的归并算法

AB是两个单链表,其中元素递增有序,将AB归并成一个按元素值非递减有序的链表CCAB中的节点组成。

具体做法描述如下:

已知AB中的元素递增有序,可以从AB中挑选最小的元素插入C的尾部,这样当AB中的元素全部都插入C中时,C一定是递增有序的。

注意:AB中的元素有可能一个已经全部被插入到C中,另一个还没有插完。若A中所有的元素已经全部被插入到C中而B还没有插完,则说明B中所有元素都大于C中元素,因此只要将B中的剩余部分链接到C的尾部即可。

Void mergeLNode *&ALNode *&BLNode *&C){

LNode *p=A->next;//p用来跟踪A的最小值结点

LNode *q=B->next;//q用来跟踪B的最小值结点

LNode *r;      //r始终指向C的终端结点

C=A;          //A的头结点来做C的头结点

C->next=NULL;

free(B);        //B的头结点已无用,则释放掉

r=C;           //r指向C,因为此时头结点也是终端结点

Whilep=NULL&&q!=NULL){//pq都不空时,选取pq所指节点中的较小者插入C尾部

/*以下的if else语句中,r始终指向当前链表的终端结点,作为接纳新节点的一个媒介,通过它新结点被链接入C并且重新指向新的终端结点,以便于接受下一个新节点,这里体现了建立链表的尾插法思想*/

If(p->data<=q->data){

r->next=p;

p=p->next;

r=r->next;

}

else{

r->next=q;

q=q->next;

r=r->next;

}

}

r->next=NULL;

/*以下两个if语句将还有剩余结点的链表链接在C的尾部*/

If(p!=NULL) r->next=p;

If(q!=NULL) r->next=q;

}

(6)采用尾插法建立双链表

void CreateDlistR(DLNode *&L,int a[],int n){

DLNode *s,*r;

int i;

L=(DLNode *)malloc(sizeof(DLNode));

L->next=NULL;

r=L

for(i=1;i<=n;++i){

s=(DLNode*)malloc(sizeof(DLNode));//创建新结点

s->data=a[i];

/*下边3个语句将s插入在L的尾部并且r指向ss->prior=r;这一句是和建立单链表不同的地方*/

r->next=s;

s->prior=r;

r=s;

}

r->next=NULL

}

(7)双链表查找结点的算法

在双链表中查找第一个结点值为x的结点。从第一个结点开始,边扫描边比较,若找到这样的结点,则返回指针,否则返回NULL。算法代码如下:

DLNOde* searchNodeDLNode *Cint x{

   DLNode *P=C->next;

   While(p!=NULL){

If(p->data==x)

break;

p=p->next;

}

return p;//如果找到,则p中内容是结点地址(循环因break结束);若没找到,

//p中内容是NULL(循环因p=NULL而结束)。因此这一句可以将题干中要 //求的两种返回值情况统一起来

}

(8)双链表插入结点的算法

假设在双链表中p所指的结点之后插入一个节点s,其操作语句为:

s->next=p->next;

s->prior=p;

p->next=s;

S->next->prior=s;//假如p指向最后一个结点,则本行可以去掉

(9)双链表删除结点

设要删除双链表中p结点的后继结点,其操作语句如下:

q=p->next;

p->next=q->next;

q->next->prior=p;

free(q);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值