2.3.2_2单链表的查找

2.3.2_2单链表的查找

1778726429814

GetElem(L,i);按位查找

LocateElem(L,e);按位查找

//按位查找,返回第i个元素(带头节点)
LNode * GetElem(LinkList L,int i){
    if(i<0)
    	return NULL;
    LNode *p;//指针p指向当前扫描到的结点
    int j=0;//当前p指向的是第几个结点
    p=L;//L指向头结点,头结点是第0个结点(不存数据)
    while (p!=NULL && j<i){//循环找到第i个结点
        p=p->next;
        j++;
    }
    return p;
}

时间复杂度o(n)

1778727405594

//按值查找,找到数据域==e的结点
LNode *LocateElem(LinkList L,ElemType e){
	LNode *p = L->next;
    //从第一个结点开始查找数据域为e的结点
    while(p!=NULL&&p->data!=e)
        p=p->next;
    return p;//找到后返回该结点指针,否则返回NULL
    
}
//求表的长度
int Length(LinkList L){
	int len = 0;
    LNode *p=L;
    while(p->next !=NULL){
        p=p->next;
        len++;
    }
    return len;
}

1778728191974

2.3.2_3单链表的建立

1778728301045

尾插法建立单链表

typedef struct LNode{//定义单链表节点类型
    ElemType data;//每个节点存放一个数据元素
    struct LNode *next;//指针指向下一个节点
}LNode,*LinkList;

//初始化一个单链表(带头节点)
bool InitList(LinkList &L){
    L = (LNode *)malloc(sizeof(LNode));//分配一个头节点
    if(L==NULL)//内存不足,分配失败
        return false;
    L->next = NULL;//头结点之后暂时还没有节点
    return true;
    
}
void test(){
	LinkList L;//声明一个指向单链表的指针
    //初始化一个空表
    InitList(L);
    //...后续代码...
}
LinkList List_TailInsert(LinkList &L){//正向建立单链表
    int x;//设ElemType为整型
    L=(LinkList)malloc(sizeof(LNode));//建立头结点
    LNode *s,*r=L;//r为表尾指针
    scanf("%d",&x);//输入结点的值
    while(x!=9999){//输入9999表示结束
		s=(LNode *)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;//r指向新的标尾结点
        scanf("%d",&x);
    }
    r->next=NULL;//尾结点指针置空
    return L;
}

1778745958424

头插法建立单链表

//后插操作,在p结点之后插入元素e
bool InserNextNode(LNode *p,ElemType e){
    if(p==NULL)
        return false;
    LNode *s = (LNode *)malloc(sizeof(LNode));
    if(s==NULL)//内存分配失败
        return false;
    s->data = e;//用结点s保存数据元素e
    s->next = p->next;
    p->next =s;//将结点s连到p之后
    return true;
    
}
LinkList List_HeadInsert(LinkList &L){//逆向建立单链表
    LNode *s;
    int x;
    L=(LinkList)malloc(sizeof(LNode));//创建头节点
    L->next=NULL;//初始为空链表
    scanf("%d",&x);//输入结点值
    while(x!=9999){//输入9999表示结束
        s=(LNode *)malloc(sizeof(LNode));//创建新结点
        s->data=x;
        s->next=L->next;
        L->next=s;//将新结点插入表中,L为头指针
        scanf("%d",&x);
    }
    return L;
}

1778746936385

2.3.3双链表

1778747345295

1778747381728

双链表的初始化(带头结点)

typedef struct DNode{
    ElemType data;
    struct DNode *prior,*next;
}DNode,*DLinklist;

//初始化双链表
bool InitDLinkList(DLinklist &L){
    L = (DNode *)malloc(sizeof(DNode));//分配一个头结点
    if(L==NULL)//内存不足,分配失败
        return false;
    L->prior = NULL;//头结点的 prior永远指向NULL
    L->next = NULL;//头结点之后暂时还没有结点
    return true;
}

void testDLinkList(){
    //初始化双链表
    DLinklist L;
    InitDLinkList(L);
    //后续代码。。。
}

双链表的插入

//在p结点之后插入s结点
bool InsertNextDNode(DNode *p,DNode *s){
    if(p==NULL || s==NULL)//非法参数
        return false;
    s->next=p->next;
    if(p->next != NULL)//如果p结点后有后继结点
        p->next->prior=s;
    s->prior=p;
    p->next =s;
    return true;
}

1778748839221

双链表的删除

//删除p结点的后继结点
bool DeleteNextDNode(DNode *p){
    if(p==NULL)
        return false;
    DNode *q = p->next;//找到p的后继结点q
    if (q==NULL)
        return false;//p没有后继
    p->next=q->next;
    if(q->next!=NULL)//q结点不是最后一个结点
        q->next->prior=p;
    free(q);//释放结点空间
    return true;
}

1778749222662

void DestroyList(DLinklist &L){
    //循环释放各个数据结点
    while(L->next!=NULL)
        DeleteNextDNode(L);
    free(L);//释放头结点
    L=NULL;//头指针指向NULL
}

双链表的遍历

//后向遍历
while(p!=NULL){
	//对接点p做相应处理,如打印
    p=p->next;
}

//前向遍历
while(p!=NULL){
    //对接点p做相应处理,
    p=p->prior;
}

//前向遍历(跳过头结点)
while(p->prior!=NUJLL){
    //对接点p做相应处理,
    p=p->prior;
}

时间复杂度O(n)

1778749645564

posted @ 2026-05-14 19:02  轻狂书生han  阅读(8)  评论(0)    收藏  举报