数据结构与算法-4

    科技2022-09-08  116

    单链表

    定义单链表结点类型

    struct LNode{ ElemType data; //数据域 struct LNode * next //指针指向下一个节点 };

    增加一个新结点:在内存中申请一个结点所需空间,并用指针p指向这个结点

    struct LNode * p = (struct *) malloc (sizeof(struct LNode));

    ps: struct写的很麻烦,所以可以用typedef, typedf <数据类型><小名>

    typedef int zhengshu; typedef int * zhengshuzhizhen zhengshu x = 1//int x = 1 ; zhengshuzhizhen * p//int * p;

    所以增加一个新结点就可以写成

    typedef struct LNode LNode; LNode * p = (LNode *) malloc (seizeof(LNode));

    但是这还不够简洁 课本中是这样写的

    typedef struct LNode { ElemType data; //数据域 struct LNode * next //指针指向下一个节点 }LNode, * LinkList;

    其实相当于

    struct LNode{ ElemType data; //数据域 struct LNode * next //指针指向下一个节点 }; typedef struct LNode LNode; typedef struct LNode * LinkList;

    把struct LNode重命名为LNode 并且用LinkList来表示这是一个指向LNode的指针

    要表示一个单链表是,只需要声明一个头指针L,指向单链表第一个结点(找到第一个结点,就相当于找到整个单链表)

    LNode *L;//声明一个指向单链表第一个结点的指针

    LinkList L//声明一个指向单链表第一个结点的指针

    这两种表现方式作用是一样的,但是强调这是一个单链表用LinkList,强调这是一个结点用LNode *。

    不带头结点的单链表

    #include <iostream> #include <stdlib.h> using namespace std; typedef struct { ElemType data; //数据域 struct LNode * next //指针指向下一个节点 }LNode, * LinkList; //初始化一个空的表 bool InitList(LinkList &L) { L = NULL; //空表,暂时没有任何结点(防止脏数据) return true; } void test(){ LinkList L;//声明一个指向单链表的指针 InitList(L) } //判断单链表是否为空 bool Empty(LinkList L){ return (L == NULL); }

    带头结点的单链表

    #include <iostream> #include <stdlib.h> using namespace std; typedef struct { 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) } //判断单链表是否为空 bool Empty(LinkList L){ if(L->next == NULL) return true; else return false; }

    按位序插入

    bool ListInsert(LinkList &L, int i, ElemType e ){ if(i<1) return false; LNode * p; //指针p指向当前扫描到的结点 int j = 0; //记录当前p指向的是第几个结点 P = L; //L指向头结点,头结点是第0个结点 while (p != NULL && j < i-1 ){//循环到第i-1个结点 p = p->next; j++; } if(p == NULL) //p值不合法 return false; LNode * s = (LNode *)malloc(sizeof(LNode)); s->data = e; s->next = p->next; p->next = s; return true; }

    指定结点的后插操作

    bool InserNextNode (LNode * p, ElemType e){ if (p == NULL) return false; LNode * s = (LNode *)malloc(sizeof(LNode)); if(s == NULL) //内存分配失败,计算机被榨干 retuen false; //一般不会出现,只是有可能 s->data = e; //用结点s保存要插入的数据元素e s->next = p ->next; p -> next = s; return true; }

    指定结点前插(这个牛)

    bool InserPriorNode(LNode * p, ElemType e){ if (p == NULL) return false; LNode * s = (LNode *)malloc(sizeof(LNode)); if(s == NULL) retuen false; s->next = p->next; p->next = s; //新结点s连到p之后 s->data = p->data; //将p中元素复制到s中 p->data = e; //p中元素覆盖为e return true; }

    按位序删除

    bool ListDelete(LinkList &L, int i, ElemType &e ){ if(i<1) return false; LNode * p; //指针p指向当前扫描到的结点 int j = 0; //记录当前p指向的是第几个结点 P = L; //L指向头结点,头结点是第0个结点 while (p != NULL && j < i-1 ){//循环到第i-1个结点 p = p->next; j++; } if(p == NULL) //p值不合法 return false; if(p->next == NULL) //第i-1个结点之后已无其他结点 LNode * q = p->next //令q指向被删除结点 e = q->data; //用e返回元素的值 & p->next = q->next; //将*q结点从链中断开 free (q); //释放 return true; }
    Processed: 0.009, SQL: 9