zoukankan      html  css  js  c++  java
  • 双向链表

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <malloc.h>
      4 #include <stdlib.h>
      5 
      6 #define OVERFLOW 0
      7 #define TRUE true
      8 #define FALSE false
      9 #define OK 1
     10 #define ERROR 0
     11 
     12 typedef int ElemType;
     13 typedef bool Status;
     14 
     15 
     16 typedef struct DuLNode{
     17     //定义自己的数据类型
     18     ElemType data;
     19     struct DuLNode *prior, *next;
     20 }DuLNode, *DuLinkList;
     21 
     22 //带头节点的双向循环链表的基本操作
     23 void InitList(DuLinkList *L){
     24     //产生空的双向循环链表
     25     *L = (DuLinkList)malloc(sizeof(DuLNode));
     26     if(*L){
     27         (*L)->next = (*L)->prior = *L;
     28     }
     29     else{
     30         exit(OVERFLOW);
     31     }
     32 }
     33 
     34 //销毁循环链表L
     35 void DestroyList(DuLinkList *L){
     36     DuLinkList q, p = (*L)->next; //p指向第一个结点
     37     while(p != *L){
     38         q = p->next;
     39         free(p);
     40         p = q;
     41     }
     42     free(*L);
     43     *L = NULL;
     44 }
     45 
     46 //重置链表为空表
     47 void ClearList(DuLinkList L){//不改变L
     48     DuLinkList q, p = L->next; //p指向第一个结点
     49     while(p != L){//p没到表头
     50         q = p->next;
     51         free(p);
     52         p = q;
     53     }
     54     L->next = L->prior = L; //头结点的两个指针域均指向自身
     55 }
     56 
     57 //验证是否为空表
     58 Status ListEmpty(DuLinkList L){
     59     //初始条件:线性表L已存在
     60     if(L->next == L && L->prior == L){
     61         return TRUE;
     62     }
     63     else{
     64         return FALSE;
     65     }
     66 }
     67 
     68 //计算表内元素个数
     69 int ListLength(DuLinkList L){
     70     //初始条件:L已存在
     71     int i = 0;
     72     DuLinkList p = L->next; //p指向第一个结点
     73     while(p != L){ //p没到表头
     74         i++;
     75         p = p->next;
     76     }
     77     return i;
     78 }
     79 
     80 //赋值
     81 Status GetElem(DuLinkList L, int i, ElemType *e){
     82     //当第i个元素存在时,其赋值给e并返回OK,否则返回ERROR
     83     int j = 1//j为计数器
     84     DuLinkList p = L->next; //p指向第一个结点
     85     while(p != L && p->next){
     86         j++;
     87     }
     88     if(p == L || j < i){//第i个元素不存在
     89         return ERROR;
     90     }
     91     *e = p->data; //取第i个元素
     92     return OK;
     93 }
     94 
     95 Status compare(ElemType e1, ElemType e2){
     96     if(e1 == e2){
     97         return TRUE;
     98     }
     99     else{
    100         return FALSE;
    101     }
    102 }
    103 
    104 //查找元素
    105 int LocateElem(DuLinkList L, ElemType e, Status(*cmppare)(ElemType, ElemType)){
    106     //初始条件:L已存在, compare是数据元素判定函数
    107     //操作结果:返回L中第一个与e满足关系compare()的数据元素位序
    108     //若这样的数据元素不存在,则返回值为0
    109     int i = 0;
    110     DuLinkList p = L->next;  //p指向第一个元素
    111     while(p != L){
    112         i++;
    113         if(compare(p->data, e)){//找到这样的数据元素
    114             return i;
    115         }
    116         p = p->next;
    117     }
    118     return 0;
    119 }
    120 
    121 
    122 //查找元素前驱
    123 Status PriorElem(DuLinkList L, ElemType cur_e, ElemType *pre_e){
    124     //操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱
    125     //否则操作失败,pre_e无定义
    126     DuLinkList p = L->next->next;  //p指向第二个元素
    127     while(p != L){ //p没到表头
    128         if(p->data == cur_e){
    129             *pre_e = p->prior->data;
    130             return TRUE;
    131         }
    132         p = p->next;
    133     }
    134     return FALSE;
    135 }
    136 
    137 //查找后继元素
    138 Status NextElem(DuLinkList L, ElemType cur_e, ElemType *next_e){
    139     //操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回她的后继
    140     //否则操作失败,next_e无定义
    141     DuLinkList p = L->next->next; //p指向第二个元素
    142     while(p != L){
    143         if(p->prior->data == cur_e){
    144             *next_e = p->data;
    145             return TRUE;
    146         }
    147         p = p->next;
    148     }
    149     return FALSE;
    150 }
    151 
    152 //查找元素地址
    153 DuLinkList GetElemP(DuLinkList L, int i){//另加
    154     //在双向链表L中返回第i个元素的地址,i为0,则返回头结点的地址,若第i个元素不存在,则返回NULL
    155     int j;
    156     DuLinkList p = L; //p指向头结点
    157     if(i < 0 || ListLength(L)) {//i值不合法
    158         return NULL;
    159     }
    160     for(j = 1; j <= i; j++){
    161         p = p->next;
    162     }
    163     return p;
    164 }
    165 
    166 //元素的插入
    167 Status lisInsert(DuLinkList L, int i, ElemType e){
    168     //在带头结点的双向循环链表L中的第i个位置之前插入元素e,i的合法值为1<= i <= 表长 + 1
    169     //改进算法2.18,否则无法在第表长+1个节点之前插入元素
    170     DuLinkList p, s;
    171     if(i < 1 || i > ListLength(L) + 1){ //i值不合法
    172         return ERROR;
    173     }
    174     p = GetElemP(L, i - 1);//在L中确定第i个元素的前驱的位置指针p
    175     if(!p){ //p = NULL,即第i个元素的前驱不存在(设头结点为第1个元素的前驱)
    176         return ERROR;
    177     }
    178     s = (DuLinkList)malloc(sizeof(DuLNode));
    179     if(!s){
    180         return OVERFLOW;
    181     }
    182     s->data = e;
    183     s->prior = p;  //在第i-1个元素之后插入
    184     s->next = p->next;
    185     p->next->prior = s;
    186     p->next = s;
    187     return OK;
    188 }
    189 
    190 //元素的删除
    191 Status ListDelete(DuLinkList L, int i, ElemType *e){
    192     //删除带头结点的双向循环链表L的第i个元素,i的合法值为1<= i <= 表长
    193     DuLinkList p;
    194     if(i < 1){//i值不合法
    195         return ERROR;
    196     }
    197     p = GetElemP(L, i);//在L中确定第i个元素的位置指针p
    198     if(!p){//p=NULL,即第i个元素不存在
    199         return ERROR;
    200     }
    201     *e = p->data;
    202     p->prior->next = p->next;
    203     p->next->prior = p->prior;
    204     free(p);
    205     return OK;
    206 }
    207 
    208 void *visit(ElemType e){
    209     //TODO
    210 }
    211 //正序查找
    212 void ListTraverse(DuLinkList L, void(*vist)(ElemType)){
    213     //由双链循环线性表L的头结点出发,正序对每个元素调用函数visit()
    214     DuLinkList p = L->next;//p指向头结点
    215     while(p != L){
    216         visit(p->data);
    217         p = p->next;
    218     }
    219     printf(" ");
    220 }
    221 
    222 //逆序查找
    223 void ListTraverseBack(DuLinkList L, void(*visit)(ElemType)){
    224     //由双链循环线性表L的头结点出发,逆序对每个元素调用函数visit(),另加
    225     DuLinkList p = L->prior;//p指向头结点
    226     while(p != L){
    227         visit(p->data);
    228         p = p->prior;
    229     }
    230     printf(" ");
    231 }
    232 
    233 int main(){
    234     return 0;
    235 }
  • 相关阅读:
    Python_Excel文件操作
    Python_CRC32
    Python_替换当前目录下文件类型
    Python_os、os.path、os.shutil使用案例
    Python_文件与文件夹操作
    MyBatis/Ibatis中#和$的区别
    遍历listmap 遍历map
    jquery操作select(取值,设置选中)
    ==与===区别(两个等号与三个等号)
    常用map总结
  • 原文地址:https://www.cnblogs.com/angle-qqs/p/4026130.html
Copyright © 2011-2022 走看看