DataStructure_Singly Linked List


1_单链表的基本操作:

1.1_表的声明
typedef int ElemType;
typedef struct LNode{
    ElemType data;       //数据域
    struct LNode *next;  //指针域
}LNode,*LinkList;
1.2_头插法(可以实现表的逆置)
//头插法  实现的是倒叙输出
LinkList List_HeadInsert(LinkList &L){
    LNode *s;
    int x;
    L=(LinkList) malloc (sizeof(LNode));
    L->next = NULL;
    scanf("%d",&x);
    while(x!=999){
        s = (LNode*) malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;
        scanf("%d",&x);
    }
    return L;
}
程序输入:
1 2 3 4 5 999
程序输出:
5 4 3 2 1
1.3_尾插法(正向建立单链表)
//尾插法 也就是在最后的一个元素插入
LinkList List_TailInsert(LinkList &L){
    int x;
    L = (LinkList) malloc(sizeof (LNode));
    LNode *s,*r = L;
    scanf("%d",&x);
    while (x!=999){
        s = (LinkList) malloc(sizeof (LNode));
        s->data = x;        //声明一个内存放数据元素
        r ->next = s;       //使我们的r的next指向s [rs] => [r]->[s]
        r = s;              //然后又让我们的rs呆在一起继续合作[r]->[s]=>[rs]即指向尾节点
        scanf("%d",&x);
    }
    r->next=NULL;           //r最后指向NULL 即为为尾节点
    return L;               //给用户返回单链表
}
程序输入:
1 2 3 4 5 999
程序输出:
1 2 3 4 5
1.4_指定位序插入
//插入元素 在指定的位置插入
void  Insert(LinkList &L,int i,ElemType E){
    LNode *p;
    LNode *s = (LNode*)malloc(sizeof (LNode));
    s->data = E;
    s->next = NULL;
    p = GetElem(L,i-1);
    if(p!=NULL){
        s->next = p->next;
        p->next = s;
    }else{
        cout<<"插入值非法"<<endl;
    }

}
程序输入:
1 2 3 4 5 999
程序输出:
5 4 3 2 1
在第三个位置插入元素10
5 4 10 3 2 1
1.5_查找第i个元素(位序查找)
//查找第i个元素值
LNode *GetElem(LinkList L,int i){
    int j = 1;
    LNode *p = L->next;
    if (i == 0){
        return L;
    }
    if (i < 1){
        return NULL;
    }
    while (p->next!=NULL&&j<i)
    {
        p=p->next;
        j++;
    }
    return p;
}
程序输入:
1 2 3 4 5 999
程序输出:
5 4 3 2 1
这是按位序查找,查找(位序为1)的元素的值:5
1.6_指定元素查找
//找到指定元素的位序
//int e就是我们需要找到的元素如果有返回数据[data[next]]
LNode *FindByEle(LinkList L,int e){
    LNode *p = L->next;
    while(p!=NULL && p->data!=e){
        p = p->next;
    }
    return p;
}
程序输入:
1 2 3 4 5 999
程序输出:
5 4 3 2 1
找到元素为三的元素:3
1.7_打印单链表
//打印单链表
void PrintLinkList(LinkList L){
    LNode *tmp = L->next;		//这里我们开始第一个元素
    if (tmp == NULL){			//如果第一个元素的值为null即为空
       printf("链表为空");	
    }
    while(tmp != NULL){			//循环取数据
        cout<<tmp->data<<" ";
        tmp = tmp->next;
    }
}
1.8_按位序删除某个节点
//按位序删除节点
void Delete_LinkList(LinkList &L,int i,ElemType &e){
    //p所指的节点是q所指的节点的前驱节点
    LNode *p;
    LNode *q = (LNode*) malloc(sizeof (LNode));
    p = GetElem(L,i-1);			//我们调用了上面GetElem但是实际上我们取的是第i-1个元素
    if(p==NULL || p->next==NULL){
        cout<<"非法删除"<<endl;
        free(q);
    }
    q=p->next;                  //我们从上面的i-1得到第i-1个元素
    e = q->data;				//取出删除节点的数据
    p->next = q->next;          //声明一个新节点接受i-1的next 也就是我们要删除的节点
    free(q);                    //我们再free之前就先把i-1的next指向i的next就很OK!
程序输入:
1 2 3 4 5 999
程序输出:
5 4 3 2 1
这是按位序删除(位序为2),被删除的元素值:4
5 3 2 1
1.9_删除某个节点的时间复杂度为O(1)的
bool DeleteNode(LNode *p){
	if(p==NULL){
		return false;
	}
	LNode *q = p->next;			//令q指向*p的后继节点 
	p->data=p->next->data;		//和后继节点交换数据 
	p->next=q->next;			//将*q节点从链中"断开" 
	free(p);					//释放 
	return true;
}

注释:
	我们想要删除
	[1]->[2]->[3]->[4]....
	通过上面的GetElem得到想要删除的节点p。在这里我们假设是第三个
	1、那么平时的做法就是头开始遍历。使得[2]->next = [3]->next 即是[2]->[4] 释放[3]就可以了
	2、这个做法是我们虽然不能移动指针但是数据可以移动。即将[4]的数据转移到[3]上来 释放[4]即可
	那么[3]->data = [4]->data也就是我们上面的[p[3]->data=[p->next][4]->data]。断开[4]
	即是[p[3]->next=q[4]->next]。为了方便理解我们假设在[4]后有一个[5].那么[4]->next = [5]不是吗?是不是特别容易理解!
	
	我可真聪明哈哈哈哈!

2_全部代码

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

typedef int ElemType;
typedef struct LNode{
    ElemType data;      //数据域
    struct LNode *next;  //指针域
}LNode,*LinkList;
//头插法  实现的是倒叙输出
LinkList List_HeadInsert(LinkList &L){
    LNode *s;
    int x;
    L=(LinkList) malloc (sizeof(LNode));
    L->next = NULL;
    scanf("%d",&x);
    while(x!=999){
        s = (LNode*) malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;
        scanf("%d",&x);
    }
    return L;
}
//打印单链表
void PrintLinkList(LinkList L){
    LNode *tmp = L->next;
    if (tmp == NULL){
       printf("链表为空");
    }
    while(tmp != NULL){
        cout<<tmp->data<<" ";
        tmp = tmp->next;
    }
}
//找到指定元素的位序
LNode *FindByEle(LinkList L,int e){
    LNode *p = L->next;
    while(p!=NULL && p->data!=e){
        p = p->next;
    }
    return p;
}
//查找第i个元素值
LNode *GetElem(LinkList L,int i){
    int j = 1;
    LNode *p = L->next;
    if (i == 0){
        return L;
    }
    if (i < 1){
        return NULL;
    }
    while (p->next!=NULL&&j<i)
    {
        p=p->next;
        j++;
    }
    return p;
}
//按位序删除节点
void Delete_LinkList(LinkList &L,int i,ElemType &e){
    //p所指的节点是q所指的节点的前驱节点
    LNode *p;
    LNode *q = (LNode*) malloc(sizeof (LNode));
    p = GetElem(L,i-1);
    if(p==NULL || p->next==NULL){
        cout<<"非法删除"<<endl;
        free(q);
    }
    q=p->next;                  //我们从上面的i-1得到第i-1个元素
    e = q->data;
    p->next = q->next;          //然后在声明一个新节点接受i-1的next 也就是我们要删除的节点
    free(q);                    //我们再free之前就先把i-1的next指向i的nextfree就没事啦

}
//插入元素 在指定的位置插入
void  Insert(LinkList &L,int i,ElemType E){
    LNode *p;
    LNode *s = (LNode *)malloc(sizeof (LNode));
    s->data = E;
    s->next = NULL;
    p = GetElem(L,i-1);
    if(p!=NULL){
        s->next = p->next;
        p->next = s;
    }else{
        cout<<"插入值非法"<<endl;
    }

}
//尾插法 也就是在最后的一个元素插入
LinkList List_TailInsert(LinkList &L){
    int x;
    L = (LinkList) malloc(sizeof (LNode));
    LNode *s,*r = L;
    scanf("%d",&x);
    while (x!=999){
        s = (LinkList) malloc(sizeof (LNode));
        s->data = x;        //声明一个内存放数据元素
        r ->next = s;       //使我们的r的next指向s [rs] => [r]->[s]
        r = s;              //然后又让我们的rs呆在一起继续合作  [r]->[s] => [rs] 即指向尾节点
        scanf("%d",&x);
    }
    r->next=NULL;           //r最后指向NULL 即为为尾节点
    return L;               //给用户返回单链表
}
int main() {

    LinkList L;

    List_HeadInsert(L);
    PrintLinkList(L);
    int e;
    Delete_LinkList(L,2,e);
    cout<<"\n"<<"这是按位序删除(位序为2),被删除的元素值:"<<e<<endl;
    PrintLinkList(L);
    //查找第i个元素
    cout<<"\n"<<"这是按位序查找,查找(位序为1)的元素的值:"<<GetElem(L,1)->data<<endl;
    LNode *pNode = FindByEle(L, 3);
    cout<<"找到元素为三的元素:"<<pNode->data<<endl;
    //在第三个位置插入元素10
    cout<<"在第三个位置插入元素10"<<endl;
    Insert(L,3,10);
    PrintLinkList(L);
    return 0;

    LinkList TailL;
    List_TailInsert(TailL);
    PrintLinkList(TailL);



}
程序输入:
1 2 3 4 5 999
程序输出:
5 4 3 2 1
这是按位序删除(位序为2),被删除的元素值:4
5 3 2 1
这是按位序查找,查找(位序为1)的元素的值:5
找到元素为三的元素:3
在第三个位置插入元素10
5 3 10 2 1

文章作者: SC
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 SC !
评论
  目录