单链表操作_更新中

#include "stdafx.h"
#include <iostream>
using namespace std;


typedef struct Node{
int data;
struct Node *next;
}LinkList;
/*
//链表的建立(无头结点):尾插法——插入元素后为正序;
LinkList *createTailList()
{
LinkList *s,*r,*L;
int x;
L=NULL;
r=NULL;
scanf("%d",&x);
while(x!=-1)
{
s=(LinkList *)malloc(sizeof(LinkList));
s->data = x;
if(!L) L=s;
else r->next =s;
r =s;
scanf("%d",&x);
}
if(r) r->next = NULL; //尾结点的指针域置空
return L;
}
*/
//尾插法,带头结点的方式:
LinkList *createTailList()
{ LinkList *L = (LinkList *)malloc(sizeof(LinkList));
LinkList *s,*r=L; //尾指针指向头结点
int x;
scanf("%d",&x);
while(x!=-1)
{
s=(LinkList *)malloc(sizeof(LinkList));
s->data = x;
r->next = s; //把新结点插入到尾指针后
r=s; //r指向新的尾结点
scanf("%d",&x);
}
r->next = NULL; //尾结点的指针域置空
return L;
}


//查找运算
//1.按序号查找:
//在带头结点的单链表L中,查找第i个结点
LinkList *getElem(LinkList *L,int i)
{
LinkList *p =L;
int j=0;
while(p&&j<i) //从头结点开始扫描
{
p=p->next;
j++;
}
if(!p||(j>i)) //j>i表示输入了小于0的位置
{
printf("\n位置出错\n");
return NULL;
}
else
return p;
}
//求带头结点的单链表的长度
int lengthList(LinkList *L)
{
LinkList *p = L->next; //p指向首结点
int j=0;
while(p)
{
p=p->next;
j++;
}
return j; //线型表的长度不包括头结点
}


//(2)按值查找
LinkList *locateElem(LinkList *L, int x) //x的类型视具体情况定
{
LinkList *p =L->next; //注意是从首结点开始的(非头结点)
while(p&&p->data!=x)
p=p->next;
return p;
}
//插入算法:在指定结点
//结点的插入(在非空结点p后插入)时间复杂度为O(1)
void insertAfterElemNode(LinkList *p,int x)
{
LinkList *s;
s=(LinkList *)malloc(sizeof(LinkList)); //分配空间
s->data =x; //别忘记赋值
s->next = p->next;
p->next = s;
}
//指定结点p前插入元素,首先要找到p前面的结点
void insertBeforeElemNode(LinkList *L,LinkList *p,int x)
{ //在带头结点的单链表L中p所指的结点前插入值为x的元素
LinkList *s,*q;
q=L;
s=(LinkList *)malloc(sizeof(LinkList)); //分配空间
s->data =x; //别忘记赋值
while(q->next!=p)
{
q=q->next;
}
s->next = p;
q->next = s;
}
//插入算法:在指定位置
//在第i个结点前插入数据元素x

//带头结点的单链表L中第i个元素前插入值为x的原色
int insertElem(LinkList *L, int i,int x)
{
LinkList *p, *s;
int j=0;
p=L;
while(p&&j<i-1) //找到第i-1个元素的地址
{
p=p->next;
j++;
}
if((!p)||(j>i-1))
{printf("error");return 0;}
s=(LinkList *)malloc(sizeof(LinkList)); //分配空间
s->data =x ; //别忘记赋值


s->next  = p->next;
p->next =s;
return 1; //返回1表示插入成功
}
//删除算法
//1.给定结点时,删除
//删除结点p
void deleteElemNode(LinkList *L, LinkList *p)
{
LinkList *q = L;
while(q->next!=p)
q=q->next;


q->next =p->next;
free(p); //别忘记了!!释放p占用的空间
}


//删除带头结点的单链表L中的重复结点(思路:从首结点开始,第一个和剩下的一次比较,有重复的删除;再第二个结点和后面的结点一次比较...)
int deleteDupNode(LinkList *L)   //此函数有问题!!!!!!!!!!!!!
{
LinkList *p,*q,*r;
p =L->next;
if(!p) return 0; //空链表 直接返回
while(p->next){
q=p;
while(q->next)
{
if(p->data!=q->next->data)
q=q->next;
else
{
r = q->next;
q->next=r->next;
free(r);
}
}
p=p->next;
}
return 1;
}
//单链表L的逆置(带头结点),不重复申请结点空间
//头插法方法逆置单链表(头插法本来插入后就是逆序的)
void reverse(LinkList *L)
{ LinkList *q;
LinkList *p = L->next; //p指向第一个数据结点
L->next =NULL; //使得第一个数据结点可以指向空
while(p)
{
q=p;
p=p->next;
q->next = L->next;
L->next =q;

}
}
//两个单链表A和B,归并到C;算法复杂度为O(m+n)
//思路:设两个指针p和q,分别指向当前正在比较的结点,比较数据域的大小,较小的取出,头插到C表的头部
LinkList *unionAB(LinkList *A,LinkList *B)
{
LinkList *C,*p,*q,*s; //p,q指向当前比较结点;s是临时存储结点;
p=A->next;
q=B->next; //指向第一个数据点
C=A;
C->next = NULL; //利用头插法,所以头结点置空
while(p&&q)
{
if(p->data<=q->data)
{
s=p;
p=p->next;
}
else
{
s=q;
q=q->next;
}
s->next = C->next;
C->next= s;
}
if(!q) q=p; //q为空了,将剩余结点形成的链的链头保存到q中
while(q)
{
s=q;
q=q->next;
s->next = C->next; //
C->next = s; //这俩句是典型的头插法(倒着插入)
}
free(B);
return C;
}
void printfLinkList(LinkList *L) //x的类型视具体情况定
{
LinkList *p =L->next; //注意是从首结点开始的(非头结点)
while(p){
cout<<"链表中的节点值:"<<p->data<<endl;
p=p->next;
}
}
int main()
{
/*归并
LinkList *LA =createTailList();
LinkList *LB =createTailList();
LinkList *LC =unionAB(LA,LB);
printfLinkList(LC);
*/
/*逆序
LinkList *LA =createTailList();
reverse(LA);
printfLinkList(LA);
*/


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值