数据结构笔记(一) 线性表(C语言描述)

数据结构(一) 线性表

顺序表

存储结构

#define ElemType int
#define MAXSIZE 100
typedef struct{
    ElemType *elem;//初始地址
    int length;//长度
}SqList;

初始化

//初始化
void init(SqList& L){
    
    
    L.elem = new ElemType[MAXSIZE];
    if(!L.elem){
    
    
        cout << "内存分配失败" << endl;
        return;
    }
    L.length = 0;
}

创建长度为n的顺序表

void createList(SqList &L, int n){
    
    
    if(n <= 0 || n > MAXSIZE){
    
    
        cout << "n值不合法" << endl;
        return;
    }
    L.length = 0;
     cout << "请输入线性表" << n << "个数据:";
    for(int i = 0; i < n; i++){
    
    
        cin >> L.elem[i];
        L.length++;
    }
}

获取第i个元素

//获取第i个元素
ElemType getElem(SqList L, int i){
    
    
    if(i < 1 || i > L.length){
    
    
        cout << "输入的下标有误" << endl;
        return 0;
    }
    return L.elem[i - 1];
}

查找某个元素

//查找某个元素,找到返回位置,找不到返回0
int locateElem(SqList L, ElemType e){
    
    
    for(int i = 0; i < L.length; i++){
    
    
        if(e == L.elem[i]){
    
    
            return i + 1;
        }
    }
    return 0;
}

在第i个元素插入元素

//在第i个位置插入元素e
void ListInsert(SqList &L, int i, ElemType e){
    
    
    if((i < 1) || (i > L.length + 1)){
    
    
        cout << "i值不合法" << endl;
        return;
    }
    if(L.length == MAXSIZE){
    
    
        cout << "存储空间已满" << endl;
        return;
    }
    for(int j = L.length; j >= i; j--){
    
    
        L.elem[j] = L.elem[j - 1];
    }
    L.elem[i - 1] = e;
    ++L.length;
}

删除第i个元素

//删除第i个元素
void ListDelete(SqList &L, int i){
    
    
    if(i < 1 || i > L.length){
    
    
        cout << "i值不合法" << endl;
        return;
    }

    for(int j = i; j < L.length; j++){
    
    
        L.elem[j - 1] = L.elem[j];
    }
    L.length--;
}

链表

存储结构

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

初始化

//初始化
bool init(LinkList &L){
    
    
    L = new LNode;
    if(!L){
    
    
        cout << "内存分配失败" << endl;
        return false;
    }
    L->next = NULL;
    return true;
}

取值

//取出第i个元素的值
bool getElem(LinkList L, int i, ElemType &e){
    
    
    LNode* p = L->next;
    int j = 1;
    while(p && j < i){
    
    
        p = p->next;
        ++j;
    }
    if(!p || j > i){
    
    
        cout << "i值不合法" << endl;
        return false;
    }
    e = p->data;
    return false;
}

查找

//查找值为e的元素,返回节点
LNode *LocateElem(LinkList L, ElemType e){
    
    
    LNode *p = L->next;
    while(p != NULL){
    
    
        if(p->data == e){
    
    
            break;
        }
        p = p->next;
    }
    return p;
}

插入

//在第i个元素中插入元素
bool ListInsert(LinkList &L, int i, ElemType e){
    
    
    LNode *p = L;
    int j = 0;
    while(p != NULL){
    
    
        p = p->next;
        j++;
        if(j == i - 1){
    
    
            break;
        }
    }
    if(!p || j > i - 1){
    
    
        return false;
    }
    LNode *s = new LNode;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

删除

//删除第i个元素
bool ListDelete(LinkList &L, int i){
    
    
    LNode *p = L;
    int j = 0;
    while(p != NULL){
    
    
        p = p->next;
        j++;
        if(j == i - 1){
    
    
            break;
        }
    }
    if(!p || j > i - 1){
    
    
        return false;
    }
    LNode *s = p->next;
    p->next = s->next;
    delete s;
    return true;
}

前插法创建链表

//前插法创建链表
void creatListH(LinkList &L, int n){
    
    
    L = new LNode;
    L->next = NULL;
    LNode *p;
    cout << "依次输入" << n << "个节点的值:";
    for(int i = 0; i < n; i++){
    
    
        p = new LNode;
        cin >> p->data;
        p->next = L->next;
        L->next = p;
    }
}

后插法创建链表

//后插法创建链表
void creatListR(LinkList &L, int n){
    
    
    L = new LNode;
    L->next = NULL;
    LNode *r = L;//尾指针
    LNode *p;
    cout << "依次输入" << n << "个节点的值:";
    for(int i = 0; i < n; i++){
    
    
        p = new LNode;
        cin >> p->data;
        p->next = NULL;
        r->next = p;
        r = p;//尾指针更新
    }
}

线性表相关算法

连接两个有序链表

void mergeTwoList(LinkList &LA, LinkList &LB, LinkList &LC){
    
    
    LNode *pa = LA->next;//用于遍历LA链表
    LNode *pb = LB->next;//用于遍历LB链表
    LC = LA;//合并后的链表,让LC指向LA的头节点
    LNode *pc = LC;//用于创建合并链表
    while(pa && pb){
    
    
        if(pa->data <= pb->data){
    
    
            pc->next = pa;//连接pa节点
            pc = pa;//pc指针后移
            pa = pa->next;//pa指针后移
        }else{
    
    
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa ? pa : pb;//将非空表的剩余片段插入到pc所指节点之后
}

链表反转

void reverseList(LinkList &L){
    
    
    LNode *p = L->next;//用于遍历链表
    L->next = NULL;//原链表清除数据
    LNode *q;//用于临时保存下一个节点
    while(p){
    
    
        q = p->next;//保存下一个节点
        p->next = L->next;//让插入节点的next指向当前链表头节点的下一个节点
        L->next = p;//让当前链表头节点的下一个节点指向插入的节点
        p = q;//指针后移
    }
}

删除倒数第k个节点

void listDeleteK(LinkList &L, int k){
    
    
    int len = getLength(L);
    if(k < 0 || k > len){
    
    
        cout << "k值不合法" << endl;
        return;
    }
    int n = len - k;
    LNode *p = L;
    int t = 0;
    while(t < n){
    
    
        p = p->next;
        t++;
    }
    LNode *q = p->next;
    p->next = q->next;
    delete q;
}
int getLength(LinkList L){
    
    
    int len = 0;
    L = L->next;
    while(L){
    
    
        len++;
        L = L->next;
    }
    return len;
}

删除顺序表所有值为item的数据元素

void deleteItem(SqList &L, ElemType item){
    
    
    int count = 0;//用于记录删除掉的节点数
    for(int i = 0, j = 0; i < L.length; i++){
    
    
        if(L.elem[i] == item){
    
    
            count++;
        }else{
    
    
            L.elem[j] = L.elem[i];
            j++;
        }
    }
    L.length -= count;
}

猜你喜欢

转载自blog.csdn.net/weixin_45834777/article/details/109048917