408数据结构_单链表的存储(带头结点)

准备工作

#include 

using namespace std;

typedef int ElemType;
typedef struct LNode {
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;

初始化

bool InitList(LinkList &L) {
    L = (LNode *) malloc(sizeof(LNode));
    L->next = NULL;
    return true;
}

基本操作——插入

//插入
bool ListInsert(LinkList &L, int i, ElemType e) {
    LNode *p = L;//指针p指向当前扫描到的节点
    int j = 0;  //j用于记录当前节点的位序,头结点是0;

    // 这个while循环用于找i的前一个元素
    while (p != NULL && j < i - 1) {  //这里的p!=Null是用于控制合法范围    jnext;
        j++;

    }
    if (p == NULL) return false;   //如果添加的位序超出范围了那么 插入失败

    //这里就利用我们找到的设定插入位置的前一个元素正常插入了
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;

}

基本操作——删除

//删除
bool ListDelete(LinkList &L, int i, ElemType &e) {

    LNode *p = L;
    int j = 0;
    while (p->next != NULL && j < i - 1) {
        p = p->next;
        j++;
    }
    //---------------------------------------------------------这里之前和插入操作类似  只是p的限制条件不同。
    if (p->next == NULL || j > i - 1) return false;
    //--------------------------------------------------以下操作已经找到想要删除的位置的前一个元素 可以正常删除了
    LNode *q = p->next;
    e = q->data;
    p->next = q->next;     // 实际上断开前面的连接就完成操作了
    free(q);
    return true;
}

基本操作——查找

(1)按序号查找结点   (这是非常容易操作不过多解释,只需要找到第i个节点即可)

//查找操作
//按序号查找结点   (这是非常容易操作不过多解释,只需要找到第i个节点即可)
LNode *GetElem(LinkList L, int i) {

    LNode *p = L;
    int j = 0;
    while (p != NULL && j < i) {
        p = p->next;
        j++;
    }
    return p;
}

(2)按值查找表结点

LNode *LocateElem(LinkList L, ElemType e) {
    LNode *p = L->next;  //由于不需要记录序号 则可以跳过表头
    while (p != NULL && p->data != e) {
        p = p->next;
        return p;
    }
}

其他操作——后插操作

在p节点之后插入元素e (这个操作是为尾插法建表做铺垫)

//后插操作:在p节点之后插入元素e    (这个操作是为尾插法建表做铺垫)
//这属于知道前一个结点了所以不需要再找因此复杂度o1
bool InsertNextNode(LNode *p, ElemType e) {
    if (p == NULL)return false;
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == NULL)return false;//内存分配失败
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

其他操作——尾插法建表

//尾插法建表
LinkList List_TailInsert(LinkList &L) {  //正向建立单链表
    ElemType x;
    L = (LinkList) malloc(sizeof(LNode));
    LNode *s, *r = L;   //s是要插入的 r是指向表尾
    cin >> x;      //输入要插入的元素
    while (x != 9999) {//当元素为9999的时候即结束:
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;
        r->next = s;//有next先连接next,无next直接连
        r = s;
        cin >> x;//插入结束后再输入下一个要插入的内容
    }
    r->next = NULL; //最后将表尾的next设置为Null;
    return L;
}

其他操作——头插法建表

//单链表无法实现头插操作,但是却可以实现头插法建立单链表, 不过是把r变成了针对表头L实施尾插操作
LinkList List_HeadInsert(LinkList &L) {//逆向建立单链表
    LNode *s;
    ElemType x;
    L = (LinkList) malloc(sizeof(LNode));
    L->next = NULL;
    cin >> x;
    while (x != 9999) {
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;
        cin >> x;
    }
    return L;
}

显示化操作

void Print_All(LinkList L) {
    LinkList P = L->next;
    while (P != NULL) {
        cout << P->data;
        cout << " ";
        P = P->next;
    }
    cout << "\n";

}

完整代码如下:

#include 

using namespace std;

typedef int ElemType;
typedef struct LNode {
    ElemType data;
    struct LNode *next;
} LNode, *LinkList;


//初始化
bool InitList(LinkList &L) {
    L = (LNode *) malloc(sizeof(LNode));
    L->next = NULL;
    return true;
}

//插入
bool ListInsert(LinkList &L, int i, ElemType e) {
    LNode *p = L;//指针p指向当前扫描到的节点
    int j = 0;  //j用于记录当前节点的位序,头结点是0;

    // 这个while循环用于找i的前一个元素
    while (p != NULL && j < i - 1) {  //这里的p!=Null是用于控制合法范围    jnext;
        j++;

    }
    if (p == NULL) return false;   //如果添加的位序超出范围了那么 插入失败

    //这里就利用我们找到的设定插入位置的前一个元素正常插入了
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;

}

//删除
bool ListDelete(LinkList &L, int i, ElemType &e) {

    LNode *p = L;
    int j = 0;
    while (p->next != NULL && j < i - 1) {
        p = p->next;
        j++;
    }
    //---------------------------------------------------------这里之前和插入操作类似  只是p的限制条件不同。
    if (p->next == NULL || j > i - 1) return false;
    //--------------------------------------------------以下操作已经找到想要删除的位置的前一个元素 可以正常删除了
    LNode *q = p->next;
    e = q->data;
    p->next = q->next;     // 实际上断开前面的连接就完成操作了
    free(q);
    return true;
}

//查找操作
//按序号查找结点   (这是非常容易操作不过多解释,只需要找到第i个节点即可)
LNode *GetElem(LinkList L, int i) {

    LNode *p = L;
    int j = 0;
    while (p != NULL && j < i) {
        p = p->next;
        j++;
    }
    return p;
}

//按值查找表结点
LNode *LocateElem(LinkList L, ElemType e) {
    LNode *p = L->next;  //由于不需要记录序号 则可以跳过表头
    while (p != NULL && p->data != e) {
        p = p->next;
        return p;
    }
}


//后插操作:在p节点之后插入元素e    (这个操作是为尾插法建表做铺垫)
//这属于知道前一个结点了所以不需要再找因此复杂度o1
bool InsertNextNode(LNode *p, ElemType e) {
    if (p == NULL)return false;
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == NULL)return false;//内存分配失败
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

//尾插法建表
LinkList List_TailInsert(LinkList &L) {  //正向建立单链表
    ElemType x;
    L = (LinkList) malloc(sizeof(LNode));
    LNode *s, *r = L;   //s是要插入的 r是指向表尾
    cin >> x;      //输入要插入的元素
    while (x != 9999) {//当元素为9999的时候即结束:
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;
        r->next = s;//有next先连接next,无next直接连
        r = s;
        cin >> x;//插入结束后再输入下一个要插入的内容
    }
    r->next = NULL; //最后将表尾的next设置为Null;
    return L;
}


//单链表无法实现头插操作,但是却可以实现头插法建立单链表, 不过是把r变成了针对表头L实施尾插操作

LinkList List_HeadInsert(LinkList &L) {//逆向建立单链表
    LNode *s;
    ElemType x;
    L = (LinkList) malloc(sizeof(LNode));
    L->next = NULL;
    cin >> x;
    while (x != 9999) {
        s = (LNode *) malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;
        cin >> x;
    }
    return L;
}


void Print_All(LinkList L) {
    LinkList P = L->next;
    while (P != NULL) {
        cout << P->data;
        cout << " ";
        P = P->next;
    }
    cout << "\n";

}





int main() {
    LinkList L;
    ElemType e;
    InitList(L);
    List_TailInsert(L);

    Print_All(L);

    ListInsert(L,2,8);

    Print_All(L);

    ListDelete(L,2,e);

    Print_All(L);

    LNode *p=GetElem(L,2);

cout<data<

你可能感兴趣的:(数据结构,算法)