关于双向不循环链表的插入操作问题
#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),没有输出元素,一直在考虑如果是空表的话,插入方式是不是要更改.
一样的,画图,把图画出来代码就会写了
不画图,代码确实不会写
我也是画了图的,画了图我才会写的
#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 InitList(LinkList *L);
Status DestryList(LinkList L);
Status ListInsert(LinkList L, int i, const ElemType *e);
Status ListDelete(LinkList L, int i, ElemType *e);
Status ClearList(LinkList L);
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Status GetElem(LinkList L, int i, ElemType *e);
Status SetElem(LinkList L, int i, const ElemType *e);
Status ListTravers(LinkList L);
Status ListAppend(LinkList L, const ElemType *e);
Status InitList(LinkList *L) {
*L = new Node;
(*L)->next = NULL;
(*L)->prior = NULL;
return OK;
}
Status DestryList(LinkList L) {
ClearList(L);
delete L;
return OK;
}
Status ListInsert(LinkList L, int i, const ElemType *e) {
if(i > ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = new Node;
q->data = *e;
q->next = p->next;
q->prior = p;
p->next = q;
if(q->next) q->next->prior = q; // 注意这里
return TRUE;
}
Status ListDelete(LinkList L, int i, ElemType *e) {
if(i >= ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = p->next;
p->next = q->next;
if(q->next) q->next->prior = p; // 同样,注意这里
delete q;
return TRUE;
}
Status ClearList(LinkList L) {
ElemType e;
while(!ListEmpty(L)) ListDelete(L, 0, &e);
return OK;
}
Status ListEmpty(LinkList L) {
return ListLength(L) == 0;
}
int 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) {
if(i >= ListLength(L)) return FALSE;
LinkList p = L->next;
while(i--) p = p->next;
*e = p->data;
return TRUE;
}
Status SetElem(LinkList L, int i, const ElemType *e) {
ElemType temp;
Status s = ListDelete(L, i, &temp);
return s ? ListInsert(L, i, e) : s;
}
Status visit(ElemType e) {
cout << e << " ";
return OK;
}
Status ListTravers(LinkList L) {
ElemType e;
int length = ListLength(L);
for(int i = 0; i < length; i++) {
GetElem(L, i, &e);
visit(e);
}
cout << endl;
return OK;
}
Status ListAppend(LinkList L, const ElemType *e) {
return ListInsert(L, ListLength(L), e);
}
int main() {
LinkList L;
InitList(&L);
for(ElemType e = 0; e < 10; ++e) {
ListAppend(L, &e);
}
ListTravers(L);
DestryList(L);
return 0;
}
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);
忘记写e了
Status ListDelete(LinkList L, int i, ElemType *e) {
if(i >= ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = p->next;
p->next = q->next;
if(q->next) q->next->prior = p; // 同样,注意这里
delete q;
return TRUE;
} 那就不写e了,写什么e ?
删除的时候还要什么e ?
想要e的话,自己调用 GetElem 获取去
#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 InitList(LinkList *L);
Status DestryList(LinkList L);
Status ListInsert(LinkList L, int i, const ElemType *e);
Status ListDelete(LinkList L, int i);
Status ClearList(LinkList L);
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Status GetElem(LinkList L, int i, ElemType *e);
Status SetElem(LinkList L, int i, const ElemType *e);
Status ListTravers(LinkList L);
Status ListAppend(LinkList L, const ElemType *e);
Status InitList(LinkList *L) {
*L = new Node;
(*L)->next = NULL;
(*L)->prior = NULL;
return OK;
}
Status DestryList(LinkList L) {
ClearList(L);
delete L;
return OK;
}
Status ListInsert(LinkList L, int i, const ElemType *e) {
if(i > ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = new Node;
q->data = *e;
q->next = p->next;
q->prior = p;
p->next = q;
if(q->next) q->next->prior = q; // 注意这里
return TRUE;
}
Status ListDelete(LinkList L, int i) {
if(i >= ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = p->next;
p->next = q->next;
if(q->next) q->next->prior = p; // 同样,注意这里
delete q;
return TRUE;
}
Status ClearList(LinkList L) {
while(!ListEmpty(L)) ListDelete(L, 0);
return OK;
}
Status ListEmpty(LinkList L) {
return ListLength(L) == 0;
}
int 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) {
if(i >= ListLength(L)) return FALSE;
LinkList p = L->next;
while(i--) p = p->next;
*e = p->data;
return TRUE;
}
Status SetElem(LinkList L, int i, const ElemType *e) {
Status s = ListDelete(L, i);
return s ? ListInsert(L, i, e) : s;
}
Status visit(ElemType e) {
cout << e << " ";
return OK;
}
Status ListTravers(LinkList L) {
ElemType e;
int length = ListLength(L);
for(int i = 0; i < length; i++) {
GetElem(L, i, &e);
visit(e);
}
cout << endl;
return OK;
}
Status ListAppend(LinkList L, const ElemType *e) {
return ListInsert(L, ListLength(L), e);
}
int main() {
LinkList L;
InitList(&L);
for(ElemType e = 0; e < 10; ++e) {
ListAppend(L, &e);
}
ListTravers(L);
DestryList(L);
return 0;
}
接口尽量保持简单,功能单一
不提供没有用的功能
删除的时候要什么 e ?
人造人 发表于 2022-11-12 10:10
忘记写e了
'''
忘记写e了
Status ListDelete(LinkList L, int i, ElemType *e) {
if(i >= ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = p->next;
p->next = q->next;
if(q->next) q->next->prior = p; // 同样,注意这里
delete q;
return TRUE;
}
'''
尽量避免直接操作底层结构,因为是真的非常容易出错
这是我一直强调的东西
像这里我就忘了写e了
不过这个函数无法避免直接操作底层结构
人造人 发表于 2022-11-12 10:18
'''
忘记写e了
插入操作,① q->next = p->next;
②q->prior = p;
③p->next = q;
④ if(q->next) q->next->prior = q;
可以先完成①④再完成②③么,感觉只要不是先把p->next接到q的前面,赋值操作应该都可以的
之前一直纠结于p指针指向插入位置的前驱和后继问题,思路不够清晰.
1094570635 发表于 2022-11-12 18:18
插入操作,① q->next = p->next;
②q->prior = p;
③p->next = q;
所以画图是关键,画了图就会写了
可以先 1 4 后 2 3
Status ListInsert(LinkList L, int i, const ElemType *e) {
if(i > ListLength(L)) return FALSE;
LinkList p = L;
while(i--) p = p->next;
LinkList q = new Node;
q->data = *e;
q->next = p->next;
if(q->next) q->next->prior = q;
q->prior = p;
p->next = q;
return TRUE;
}
页:
[1]