鱼C论坛

 找回密码
 立即注册
查看: 814|回复: 8

[已解决]关于双向不循环链表的插入操作问题

[复制链接]
发表于 2022-11-12 05:53:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <iostream>
using namespace std;


#define TRUE    1
#define FALSE   0
#define OK      1
#define ERROR   0
//#define INFEASIBLE -1
//#define OVERFLOW   -2
#define MAXSIZE    100

typedef int Status;
typedef int ElemType;

typedef struct Node
{
        ElemType data;
        struct Node* prior,*next;

}Node,*LinkList;


Status visit(ElemType e);
Status InitList(LinkList* L);
Status ListEmpty(LinkList L);
Status DestryList(LinkList* L);
Status ClearList(LinkList* L);
Status ListLength(LinkList L);
Status GetElem(LinkList L, int i, ElemType* e);
int LocateElem(LinkList L, ElemType e);
Node* LocateElem2(LinkList L, ElemType e);

Status visit(ElemType e)
{
        cout << e << " ";
        return OK;
}


Status InitList(LinkList *L)
{
        *L = new Node;
        (*L)->next =NULL;
        (*L)->prior =NULL;
        return OK;
}

Status ListEmpty(LinkList L)
{
        if (L->next)
        {
                return FALSE;
                cout << "链表非空";
        }
        else
        {
                return TRUE;
                cout << "链表为空";
        }

}


Status DestryList(LinkList* L)
{
        /*LinkList p;
        while ((*L))
        {
                p = (*L);
                (*L) = (*L)->next;
                delete p;
        }
        delete (*L);
        return OK;*/

        ClearList(L);
        delete* L;
        return OK;


}


Status ClearList(LinkList* L)
{
        LinkList p, q;
        p = (*L)->next;
        while (p)
        {
                q = p->next;
                delete p;
                p = q;

        }
        (*L)->next = NULL;
        return OK;
}

Status ListLength(LinkList L)
{
        int i = 0;
        LinkList p = L->next;
        while (p)
        {
                i++;
                p = p->next;
        }
        return i;

}

Status GetElem(LinkList L,int i,ElemType *e)
{
        /*LinkList p = L->next;
        int j = 1;
        while (p&&j<i)
        {
                p = p->next;
                j++;
        }
        if (!p||j>i)
        {
                return ERROR;
        }
        *e = L->data;
        return OK;*/


        LinkList p=L->next ;
        int length = ListLength(L);
        if (i<1||i>length)
        {
                return ERROR;
        }

        for (int j=1;j<i;j++)
        {
                p = p->next;
        }
        *e = p->data;
        return OK;

}
int LocateElem(LinkList L,ElemType e)
{
        int i = 0;
        LinkList p = L->next;
        while (p)
        {
                ++i;
                if (p->data==e)
                {
                        return i;
                }
                p = p->next;

        }
        return 0;

}

Node* LocateElem2(LinkList L, ElemType e)
{
        LinkList p = L->next;
        while (p)
        {
                if (p->data==e)
                {
                        return p;
                }
                p = p->next;
        }
        return p;

}

Status ListInsert(LinkList *L ,int i,ElemType e)
{
        int length = ListLength(*L);
        if (i<1||i>length+1||length==MAXSIZE)
        {
                return ERROR;
        }
       
        LinkList p, s;
        p = (*L);
        int j = 0;
        while (p &&j<i)
        {
                p = p->next;
        }
       
       
        s = new Node;
        s->data = e;
        s->prior = p->prior;
        p->prior->next = s;
        s->next = p;
        p->prior = s;

        return OK;
       
}

Status ListTravers(LinkList L)
{
        ElemType e;
        int length = ListLength(L);
        for (int i=1;i<=length;i++)
        {
                GetElem(L, i, &e);
                visit(e);
        }
        cout << endl;
        return OK;

}

int main()
{
        int j;
        LinkList L;
        InitList(&L);

        cout << ListLength(L) << endl;
        for (j=1;j<=10;j++)
        {
                ListInsert(&L, 1, j);
        }
        ListTravers(L);
       

        return 0;
}

Status ListInsert(LinkList *L ,int i,ElemType e),没有输出元素,一直在考虑如果是空表的话,插入方式是不是要更改.
最佳答案
2022-11-12 09:58:49
一样的,画图,把图画出来代码就会写了
不画图,代码确实不会写
我也是画了图的,画了图我才会写的

1.png

  1. #include <iostream>

  2. using namespace std;

  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. //#define INFEASIBLE -1
  8. //#define OVERFLOW   -2
  9. #define MAXSIZE 100

  10. typedef int Status;
  11. typedef int ElemType;

  12. typedef struct Node {
  13.     ElemType data;
  14.     struct Node *prior, *next;

  15. } Node, *LinkList;

  16. Status InitList(LinkList *L);
  17. Status DestryList(LinkList L);
  18. Status ListInsert(LinkList L, int i, const ElemType *e);
  19. Status ListDelete(LinkList L, int i, ElemType *e);
  20. Status ClearList(LinkList L);
  21. Status ListEmpty(LinkList L);
  22. int ListLength(LinkList L);
  23. Status GetElem(LinkList L, int i, ElemType *e);
  24. Status SetElem(LinkList L, int i, const ElemType *e);
  25. Status ListTravers(LinkList L);
  26. Status ListAppend(LinkList L, const ElemType *e);

  27. Status InitList(LinkList *L) {
  28.     *L = new Node;
  29.     (*L)->next = NULL;
  30.     (*L)->prior = NULL;
  31.     return OK;
  32. }

  33. Status DestryList(LinkList L) {
  34.     ClearList(L);
  35.     delete L;
  36.     return OK;
  37. }

  38. Status ListInsert(LinkList L, int i, const ElemType *e) {
  39.     if(i > ListLength(L)) return FALSE;
  40.     LinkList p = L;
  41.     while(i--) p = p->next;
  42.     LinkList q = new Node;
  43.     q->data = *e;
  44.     q->next = p->next;
  45.     q->prior = p;
  46.     p->next = q;
  47.     if(q->next) q->next->prior = q;     // 注意这里
  48.     return TRUE;
  49. }

  50. Status ListDelete(LinkList L, int i, ElemType *e) {
  51.     if(i >= ListLength(L)) return FALSE;
  52.     LinkList p = L;
  53.     while(i--) p = p->next;
  54.     LinkList q = p->next;
  55.     p->next = q->next;
  56.     if(q->next) q->next->prior = p;     // 同样,注意这里
  57.     delete q;
  58.     return TRUE;
  59. }

  60. Status ClearList(LinkList L) {
  61.     ElemType e;
  62.     while(!ListEmpty(L)) ListDelete(L, 0, &e);
  63.     return OK;
  64. }

  65. Status ListEmpty(LinkList L) {
  66.     return ListLength(L) == 0;
  67. }

  68. int ListLength(LinkList L) {
  69.     int i = 0;
  70.     LinkList p = L->next;
  71.     while(p) {++i; p = p->next;}
  72.     return i;
  73. }

  74. Status GetElem(LinkList L, int i, ElemType *e) {
  75.     if(i >= ListLength(L)) return FALSE;
  76.     LinkList p = L->next;
  77.     while(i--) p = p->next;
  78.     *e = p->data;
  79.     return TRUE;
  80. }

  81. Status SetElem(LinkList L, int i, const ElemType *e) {
  82.     ElemType temp;
  83.     Status s = ListDelete(L, i, &temp);
  84.     return s ? ListInsert(L, i, e) : s;
  85. }

  86. Status visit(ElemType e) {
  87.     cout << e << " ";
  88.     return OK;
  89. }

  90. Status ListTravers(LinkList L) {
  91.     ElemType e;
  92.     int length = ListLength(L);
  93.     for(int i = 0; i < length; i++) {
  94.         GetElem(L, i, &e);
  95.         visit(e);
  96.     }
  97.     cout << endl;
  98.     return OK;
  99. }

  100. Status ListAppend(LinkList L, const ElemType *e) {
  101.     return ListInsert(L, ListLength(L), e);
  102. }

  103. int main() {
  104.     LinkList L;
  105.     InitList(&L);
  106.     for(ElemType e = 0; e < 10; ++e) {
  107.         ListAppend(L, &e);
  108.     }
  109.     ListTravers(L);
  110.     DestryList(L);
  111.     return 0;
  112. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-12 09:58:49 | 显示全部楼层    本楼为最佳答案   
一样的,画图,把图画出来代码就会写了
不画图,代码确实不会写
我也是画了图的,画了图我才会写的

1.png

  1. #include <iostream>

  2. using namespace std;

  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. //#define INFEASIBLE -1
  8. //#define OVERFLOW   -2
  9. #define MAXSIZE 100

  10. typedef int Status;
  11. typedef int ElemType;

  12. typedef struct Node {
  13.     ElemType data;
  14.     struct Node *prior, *next;

  15. } Node, *LinkList;

  16. Status InitList(LinkList *L);
  17. Status DestryList(LinkList L);
  18. Status ListInsert(LinkList L, int i, const ElemType *e);
  19. Status ListDelete(LinkList L, int i, ElemType *e);
  20. Status ClearList(LinkList L);
  21. Status ListEmpty(LinkList L);
  22. int ListLength(LinkList L);
  23. Status GetElem(LinkList L, int i, ElemType *e);
  24. Status SetElem(LinkList L, int i, const ElemType *e);
  25. Status ListTravers(LinkList L);
  26. Status ListAppend(LinkList L, const ElemType *e);

  27. Status InitList(LinkList *L) {
  28.     *L = new Node;
  29.     (*L)->next = NULL;
  30.     (*L)->prior = NULL;
  31.     return OK;
  32. }

  33. Status DestryList(LinkList L) {
  34.     ClearList(L);
  35.     delete L;
  36.     return OK;
  37. }

  38. Status ListInsert(LinkList L, int i, const ElemType *e) {
  39.     if(i > ListLength(L)) return FALSE;
  40.     LinkList p = L;
  41.     while(i--) p = p->next;
  42.     LinkList q = new Node;
  43.     q->data = *e;
  44.     q->next = p->next;
  45.     q->prior = p;
  46.     p->next = q;
  47.     if(q->next) q->next->prior = q;     // 注意这里
  48.     return TRUE;
  49. }

  50. Status ListDelete(LinkList L, int i, ElemType *e) {
  51.     if(i >= ListLength(L)) return FALSE;
  52.     LinkList p = L;
  53.     while(i--) p = p->next;
  54.     LinkList q = p->next;
  55.     p->next = q->next;
  56.     if(q->next) q->next->prior = p;     // 同样,注意这里
  57.     delete q;
  58.     return TRUE;
  59. }

  60. Status ClearList(LinkList L) {
  61.     ElemType e;
  62.     while(!ListEmpty(L)) ListDelete(L, 0, &e);
  63.     return OK;
  64. }

  65. Status ListEmpty(LinkList L) {
  66.     return ListLength(L) == 0;
  67. }

  68. int ListLength(LinkList L) {
  69.     int i = 0;
  70.     LinkList p = L->next;
  71.     while(p) {++i; p = p->next;}
  72.     return i;
  73. }

  74. Status GetElem(LinkList L, int i, ElemType *e) {
  75.     if(i >= ListLength(L)) return FALSE;
  76.     LinkList p = L->next;
  77.     while(i--) p = p->next;
  78.     *e = p->data;
  79.     return TRUE;
  80. }

  81. Status SetElem(LinkList L, int i, const ElemType *e) {
  82.     ElemType temp;
  83.     Status s = ListDelete(L, i, &temp);
  84.     return s ? ListInsert(L, i, e) : s;
  85. }

  86. Status visit(ElemType e) {
  87.     cout << e << " ";
  88.     return OK;
  89. }

  90. Status ListTravers(LinkList L) {
  91.     ElemType e;
  92.     int length = ListLength(L);
  93.     for(int i = 0; i < length; i++) {
  94.         GetElem(L, i, &e);
  95.         visit(e);
  96.     }
  97.     cout << endl;
  98.     return OK;
  99. }

  100. Status ListAppend(LinkList L, const ElemType *e) {
  101.     return ListInsert(L, ListLength(L), e);
  102. }

  103. int main() {
  104.     LinkList L;
  105.     InitList(&L);
  106.     for(ElemType e = 0; e < 10; ++e) {
  107.         ListAppend(L, &e);
  108.     }
  109.     ListTravers(L);
  110.     DestryList(L);
  111.     return 0;
  112. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-12 10:04:26 | 显示全部楼层
Status InitList(LinkList* L);
Status ListEmpty(LinkList L);
Status ClearList(LinkList* L);
Status GetElem(LinkList L, int i, ElemType* e);
int LocateElem(LinkList L, ElemType e);

写代码,接口要统一,不要一会有 * 了,一会又没 * 了,一会又有了
你函数调用的时候都不知道要不要取地址了,要不要解引用了
LocateElem(L, &e);
GetElem(L, *e);
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-12 10:10:05 | 显示全部楼层
忘记写e了
  1. Status ListDelete(LinkList L, int i, ElemType *e) {
  2.     if(i >= ListLength(L)) return FALSE;
  3.     LinkList p = L;
  4.     while(i--) p = p->next;
  5.     LinkList q = p->next;
  6.     p->next = q->next;
  7.     if(q->next) q->next->prior = p;     // 同样,注意这里
  8.     delete q;
  9.     return TRUE;
  10. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-12 10:12:40 | 显示全部楼层
那就不写e了,写什么e ?
删除的时候还要什么e ?
想要e的话,自己调用 GetElem 获取去

  1. #include <iostream>

  2. using namespace std;

  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. //#define INFEASIBLE -1
  8. //#define OVERFLOW   -2
  9. #define MAXSIZE 100

  10. typedef int Status;
  11. typedef int ElemType;

  12. typedef struct Node {
  13.     ElemType data;
  14.     struct Node *prior, *next;

  15. } Node, *LinkList;

  16. Status InitList(LinkList *L);
  17. Status DestryList(LinkList L);
  18. Status ListInsert(LinkList L, int i, const ElemType *e);
  19. Status ListDelete(LinkList L, int i);
  20. Status ClearList(LinkList L);
  21. Status ListEmpty(LinkList L);
  22. int ListLength(LinkList L);
  23. Status GetElem(LinkList L, int i, ElemType *e);
  24. Status SetElem(LinkList L, int i, const ElemType *e);
  25. Status ListTravers(LinkList L);
  26. Status ListAppend(LinkList L, const ElemType *e);

  27. Status InitList(LinkList *L) {
  28.     *L = new Node;
  29.     (*L)->next = NULL;
  30.     (*L)->prior = NULL;
  31.     return OK;
  32. }

  33. Status DestryList(LinkList L) {
  34.     ClearList(L);
  35.     delete L;
  36.     return OK;
  37. }

  38. Status ListInsert(LinkList L, int i, const ElemType *e) {
  39.     if(i > ListLength(L)) return FALSE;
  40.     LinkList p = L;
  41.     while(i--) p = p->next;
  42.     LinkList q = new Node;
  43.     q->data = *e;
  44.     q->next = p->next;
  45.     q->prior = p;
  46.     p->next = q;
  47.     if(q->next) q->next->prior = q;     // 注意这里
  48.     return TRUE;
  49. }

  50. Status ListDelete(LinkList L, int i) {
  51.     if(i >= ListLength(L)) return FALSE;
  52.     LinkList p = L;
  53.     while(i--) p = p->next;
  54.     LinkList q = p->next;
  55.     p->next = q->next;
  56.     if(q->next) q->next->prior = p;     // 同样,注意这里
  57.     delete q;
  58.     return TRUE;
  59. }

  60. Status ClearList(LinkList L) {
  61.     while(!ListEmpty(L)) ListDelete(L, 0);
  62.     return OK;
  63. }

  64. Status ListEmpty(LinkList L) {
  65.     return ListLength(L) == 0;
  66. }

  67. int ListLength(LinkList L) {
  68.     int i = 0;
  69.     LinkList p = L->next;
  70.     while(p) {++i; p = p->next;}
  71.     return i;
  72. }

  73. Status GetElem(LinkList L, int i, ElemType *e) {
  74.     if(i >= ListLength(L)) return FALSE;
  75.     LinkList p = L->next;
  76.     while(i--) p = p->next;
  77.     *e = p->data;
  78.     return TRUE;
  79. }

  80. Status SetElem(LinkList L, int i, const ElemType *e) {
  81.     Status s = ListDelete(L, i);
  82.     return s ? ListInsert(L, i, e) : s;
  83. }

  84. Status visit(ElemType e) {
  85.     cout << e << " ";
  86.     return OK;
  87. }

  88. Status ListTravers(LinkList L) {
  89.     ElemType e;
  90.     int length = ListLength(L);
  91.     for(int i = 0; i < length; i++) {
  92.         GetElem(L, i, &e);
  93.         visit(e);
  94.     }
  95.     cout << endl;
  96.     return OK;
  97. }

  98. Status ListAppend(LinkList L, const ElemType *e) {
  99.     return ListInsert(L, ListLength(L), e);
  100. }

  101. int main() {
  102.     LinkList L;
  103.     InitList(&L);
  104.     for(ElemType e = 0; e < 10; ++e) {
  105.         ListAppend(L, &e);
  106.     }
  107.     ListTravers(L);
  108.     DestryList(L);
  109.     return 0;
  110. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-12 10:14:03 | 显示全部楼层
接口尽量保持简单,功能单一
不提供没有用的功能
删除的时候要什么 e ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-12 10:18:44 | 显示全部楼层

'''
忘记写e了
  1. Status ListDelete(LinkList L, int i, ElemType *e) {
  2.     if(i >= ListLength(L)) return FALSE;
  3.     LinkList p = L;
  4.     while(i--) p = p->next;
  5.     LinkList q = p->next;
  6.     p->next = q->next;
  7.     if(q->next) q->next->prior = p;     // 同样,注意这里
  8.     delete q;
  9.     return TRUE;
  10. }
复制代码

'''

尽量避免直接操作底层结构,因为是真的非常容易出错
这是我一直强调的东西
像这里我就忘了写e了
不过这个函数无法避免直接操作底层结构
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-12 18:18:54 | 显示全部楼层

插入操作,① q->next = p->next;
    ②q->prior = p;
    ③p->next = q;
④ if(q->next) q->next->prior = q;
可以先完成①④再完成②③么,感觉只要不是先把p->next接到q的前面,赋值操作应该都可以的
之前一直纠结于p指针指向插入位置的前驱和后继问题,思路不够清晰.


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-12 18:48:29 | 显示全部楼层
1094570635 发表于 2022-11-12 18:18
插入操作,① q->next = p->next;
    ②q->prior = p;
    ③p->next = q;

所以画图是关键,画了图就会写了
可以先 1 4 后 2 3

  1. Status ListInsert(LinkList L, int i, const ElemType *e) {
  2.     if(i > ListLength(L)) return FALSE;
  3.     LinkList p = L;
  4.     while(i--) p = p->next;
  5.     LinkList q = new Node;
  6.     q->data = *e;
  7.     q->next = p->next;
  8.     if(q->next) q->next->prior = q;
  9.     q->prior = p;
  10.     p->next = q;
  11.     return TRUE;
  12. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 17:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表