翻转带头结点的链表后 如何正确输出?如何正确释放内存?
#include <stdio.h>
#include <stdlib.h>
#define ERROR 0
#define OK 1
#define Overflow 2
#define Underflow 3
#define NotPresent 4
#define Duplicate 5
typedef int Status;
typedef char ElemType;
typedef struct Node {
ElemType element;
Node* link;
}Node;
typedef struct {
Node* head;
int n;
}HeaderList;
Status Init(HeaderList* h)
{
h->head = (Node*)malloc(sizeof(Node));
if (!h->head) return ERROR;
h->head->link = NULL;
h->n = 0;
return OK;
}
Node* ReverseHeaderList(HeaderList* h) {
Node* prev = NULL;
Node* head = h->head/*->link*/;
Node* temp;
while (head) {
temp = head->link;
head->link = prev;
prev = head;
head = temp;
}
return prev;
}
Status Find(HeaderList h, int i, ElemType* x)
{
Node* p;
int j;
if (i < 0 || i > h.n - 1) return ERROR;
p = h.head/*->link*/;
for (j = 0; j <= i; j++) {
p = p->link;
}
*x = p->element;
return OK;
}
Status Insert(HeaderList* h, int i, ElemType x)
{
Node *pCur, *pNext;
int j;
if (i < -1 || i > h->n - 1) return ERROR;
pCur = h->head;
for (j = 0; j <= i; j++) {
pCur = pCur->link;
}
//pNext = (Node*)malloc(sizeof(Node));
pNext = new Node;
pNext->element = x;
pNext->link = pCur->link;
pCur->link = pNext;
h->n++;
return OK;
}
Status Delete(HeaderList* h, int i)
{
Node *pCur, *pPre;
if (!h->n /*|| !h->head*/) return ERROR;
if (i < 0 || i > h->n - 1) return ERROR;
pPre = h->head;
for (int j = 0; j < i; j++) {
pPre = pPre->link;
}
pCur = pPre->link;
pPre->link = pCur->link;
free(pCur);
h->n--;
return OK;
}
Status OutPut(HeaderList h)
{
Node *pCur;
if (!h.n) return ERROR;
//Version 1
pCur = h.head;//注意此处若加了link,则需先打印,再后移pCur
while (pCur->link)
{
pCur = pCur->link;//①保证了头结点的element不打印(因为无意义)
//②(遍历到倒数第二个元素时)保证了循环体内可以打印出最后一个元素
printf("%c ", pCur->element);
}
////Version 2 & 3
//pCur = h.head->link;//保证了头结点的element不打印(因为无意义)。注意此处加了link,需先打印元素,再后移pCur
//while (pCur)//循环条件若为pCur->link,则循环结束后,最后一个元素还需打印
//{
// printf("%c ", pCur->element);
// pCur = pCur->link;
//}
////printf("%c ", pCur->element);//循环条件若为pCur->link,为打印出最后一个元素,需要在循环体外加上此句。
printf("\n");
return OK;
}
//因无法与OutPut(HeaderList h)的方法匹配,只好重写。
//暂未想出更好的方法可以与上面的方法相适应。
Status OutPut(Node* node)//不同之处:此处为先打印元素,再后移指针
{
Node* p;
if (/*!L.element ||*/ !node->link) return ERROR;
p = node/*->link*/;
while (p->link)//若不判断p->link,则最后一个p无后继结点,打印最后一个p的元素后,p继续后移,之后本应退出循环却未退出,导致结尾多打印出了一个‘?’
{
printf("%c ", p->element);
p = p->link;
}
printf("\n");
return OK;
}
void Destroy(HeaderList* h)
{
Node* temp;
Node* head = h->head;
(*h).n = 0;
while (head) {
temp = head->link;
free(head);
head = temp;
}
}
int main()
{
int i;
char x;
HeaderList headerList;
Init(&headerList);
// int insert;
for (i = 0; i < 9; i++) {
Insert(&headerList, i - 1, 'a' + i);//注意插入时,下标要从-1开始!(即i-1)
}
OutPut(headerList);
Find(headerList, 0, &x);
printf("Find(headerList, 0, &x): %c ,and then delete it from the HeaderList headerList...\n", x);
Delete(&headerList, 0);
OutPut(headerList);
Insert(&headerList, 0, 'x');
printf("\nInsert(&headerList,0,'x'): \n");
OutPut(headerList);
Insert(&headerList, -1, 'y');//i = -1 插入链表的下标0处!
printf("\nInsert(&headerList,-1,'y'): \n");
OutPut(headerList);
printf("\nReverseHeaderList(&headerList): \n");
Node* reversed = ReverseHeaderList(&headerList);
HeaderList dummy;
dummy.head = reversed;
OutPut(dummy);//问题1:为什么这样输出有误?
//问题2:这样输出直接崩溃了 WHY?
//HeaderList* dummy2;
//OutPut(*dummy2);
OutPut(reversed);
Destroy(&headerList);
free(reversed);//问题3:这不报错!? 如何正确释放reversed的内存?
return 0;
}
输出结果:
a b c d e f g h i
Find(headerList, 0, &x): a ,and then delete it from the HeaderList headerList...
b c d e f g h i
Insert(&headerList,0,'x'):
b x c d e f g h i
Insert(&headerList,-1,'y'):
y b x c d e f g h i
ReverseHeaderList(&headerList):
h g f e d c x b y ? //为什么此方法输出有误?
i h g f e d c x b y
代码如上。有三个小问题写在了对应注释里。(最后8行内)
第一次提问 希望大神们多多指教> <
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题1:用你的方法将链表翻转后,y->link指向的是原来的头结点而不是NULL,所以会打印最后的问号。先输出i的原因看下面注释。
问题2:
HeaderList* dummy2;
在这里dummy是一个指针,使用前要先分配空间。所以正确代码应该如下,当然输出错误的原因和问题1一样。问题3:没看懂你的问题是要释放整个链表所有结点的空间,还是只是释放reversed,如果是后者用
delete(reversed)
就可以,因为你是使用new申请的。