鱼C论坛

 找回密码
 立即注册
查看: 3886|回复: 10

谁来答我心中的疑惑

[复制链接]
头像被屏蔽
发表于 2012-6-11 13:33:41 | 显示全部楼层 |阅读模式
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-11 14:40:09 | 显示全部楼层
首先,楼主的代码似乎有很多手误的敲错的地方。。其次,这种方法是定义了一个头结点和尾结点,各种方法都有好有坏,根据各人喜好,或者需求来选择,定义头结点的好处在于,对于插入和删除编码比较方便,不用考虑空表的特殊情况,至于尾结点,可以让在尾部插入比较方便。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
头像被屏蔽
 楼主| 发表于 2012-6-11 14:50:10 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-12 10:08:19 | 显示全部楼层
首先,这对两个结构体,我觉得写的很好。可读性也很强,第一个结构体写的是节点,第二个结构体是整个链栈,很清晰。其次,我并没有觉得它有哪个地方占用了很大的内存空间,除了节点处,基本没有其他内存占用。把节点独立出来,使得操作更方便,写节点的时候不用考虑其他的,写链栈的时候也不需要管链表,只要知道链表首地址和节点数就行了。两者之间联系越小,考虑就越简单,操作越简单,可读性越好。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-12 10:10:39 | 显示全部楼层
其实,lz可以学习下这种处理方式。把数据和结构独立出来,把结构和操作联系起来,这样写出来的代码会更好,层次性也会更强。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
头像被屏蔽
 楼主| 发表于 2012-6-12 11:45:41 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-12 16:12:24 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef int ElemType;

  4. typedef int BOOL;
  5. #define TRUE  1
  6. #define FALSE 0

  7. //链栈节点
  8. typedef struct StackNode {
  9.         ElemType data;
  10.         struct StackNode *next;
  11. } StackNode, *LinkStackPtr;

  12. //链栈
  13. typedef struct LinkStack {
  14.         LinkStackPtr top;        //栈顶
  15.         int count;                        //节点数
  16. } LinkStack;

  17. //初始化链栈
  18. BOOL InitStack(LinkStack &stack) {
  19.         stack.top = NULL;
  20.         stack.count = 0;

  21.         return TRUE;
  22. }

  23. //入栈
  24. BOOL Push(LinkStack &stack, LinkStackPtr pStackNode) {
  25.         //判断节点是否为空
  26.         if (pStackNode == NULL) {
  27.                 printf("Node doesn't exist!");
  28.                 return FALSE;
  29.         }

  30.         //新节点入栈
  31.         pStackNode->next = stack.top;
  32.         stack.top = pStackNode;        //新栈顶
  33.         stack.count++;        //节点数+1

  34.         return TRUE;
  35. }

  36. //出栈
  37. BOOL Pop(LinkStack &stack, LinkStackPtr &pStackNode) {
  38.         //判断是否栈空
  39.         if (stack.count == 0) {
  40.                 printf("Stack empty!");
  41.                 return FALSE;
  42.         }

  43.         //取出节点
  44.         pStackNode = stack.top;
  45.         stack.top = stack.top->next;
  46.         pStackNode->next = NULL;
  47.         //节点数-1
  48.         stack.count--;

  49.         return TRUE;
  50. }

  51. //创建节点
  52. LinkStackPtr CreateNode(ElemType data) {
  53.         //申请空间
  54.         LinkStackPtr pNode = (LinkStackPtr)malloc(sizeof(StackNode));
  55.         //申请失败
  56.         if (pNode == NULL) {
  57.                 printf("Cannot apply for enough memory.");
  58.                 return NULL;
  59.         }

  60.         pNode->data = data;
  61.         pNode->next = NULL;
  62.         return pNode;
  63. }

  64. //取出节点数据
  65. ElemType GetData(LinkStackPtr pNode) {
  66.         return pNode->data;
  67. }

  68. int main(int argc, char** argv) {
  69.         //初始化栈
  70.         LinkStack stack;
  71.         InitStack(stack);

  72.         //为了方便,我就直接赋值做测试了,
  73.         //有效性检测也省了不写了
  74.         ElemType data[5];
  75.         LinkStackPtr pNode[5];
  76.         for (int i = 0; i < 5; ++i) {
  77.                 data[i] = i;
  78.                 pNode[i] = CreateNode(data[i]);
  79.         }

  80.         //入栈
  81.         Push(stack, pNode[0]);
  82.         Push(stack, pNode[1]);
  83.         Push(stack, pNode[2]);

  84.         //出栈
  85.         LinkStackPtr pTemp = NULL;
  86.         Pop(stack, pTemp);
  87.         printf("%d\n", GetData(pTemp));

  88.         return 0;
  89. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-12 16:15:33 | 显示全部楼层
本帖最后由 故乡的风 于 2012-6-12 16:17 编辑

里面我没怎么测试,期末考试临近,我也得复习。你可以自己测试下。用面向对象的思考方式学习数据结构,你会对数据结构有更深的理解。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
头像被屏蔽
 楼主| 发表于 2012-6-12 20:13:20 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-13 09:36:53 | 显示全部楼层
q5603113 发表于 2012-6-12 20:13
可我代码对比了一下,还是找不到这种代码的好处在那里,可能我对数据结构的理解还不够深刻吧

其实我的代码也写得很一般般的。我也只是写出自己的一点理解而已,也还有很多需要学习的地方
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-6-13 21:52:59 | 显示全部楼层
  1. // Stack.h
  2. typedef int ElementType;

  3. #ifndef STACK_H_
  4. #define STACK_H_

  5. // 结点的前向声明,具体实现在.c文件
  6. struct Node;
  7. typedef struct Node *PtrToNode;
  8. typedef PtrToNode Stack;

  9. int IsEmpty( Stack S );
  10. Stack CreateStack( void );
  11. void DestroyStack( Stack *S );
  12. void MakeEmpty( Stack S );
  13. void Push( ElementType X, Stack S );
  14. // 返回栈顶元素
  15. ElementType Top( Stack S );
  16. // 只弹出栈顶元素,不返回此元素
  17. void Pop( Stack S );
  18. // 弹出栈顶元素,同时返回此元素
  19. ElementType TopAndPop( Stack );
  20. #endif
复制代码
  1. // Stack.c
  2. #include "Stack.h"
  3. #include <stdlib.h>
  4. #include <assert.h>

  5. struct Node{
  6.         ElementType Element;
  7.         PtrToNode Next;
  8. };

  9. int IsEmpty( Stack S )
  10. {
  11.         return S->Next == NULL;
  12. }

  13. //************************************
  14. // Method:    CreateStack
  15. // FullName:  CreateStack
  16. // Access:    public
  17. // Returns:   Stack
  18. // Qualifier: 链式堆栈,链表带头结点
  19. // Parameter: void
  20. //************************************
  21. Stack CreateStack( void )
  22. {
  23.         Stack S;
  24.        
  25.         S = malloc( sizeof( struct Node ) );
  26.         assert( S != NULL );
  27.         S->Next = NULL;

  28.         MakeEmpty( S );

  29.         return S;
  30. }

  31. void MakeEmpty( Stack S )
  32. {
  33.         assert( S != NULL );

  34.         while( !IsEmpty( S ) )
  35.                 Pop( S );
  36. }

  37. void DestroyStack( Stack *S )
  38. {
  39.         MakeEmpty( *S );
  40.         free( *S );

  41.         // 将头结点释放后置为NULL,
  42.         // 防止悬挂指针
  43.         *S = NULL;
  44. }

  45. void Push( ElementType X, Stack S )
  46. {
  47.         PtrToNode TmpCell;

  48.         TmpCell = malloc( sizeof( struct Node ) );
  49.         assert( TmpCell != NULL );

  50.         TmpCell->Element = X;
  51.         TmpCell->Next = S->Next;
  52.         S->Next = TmpCell;
  53. }

  54. ElementType Top( Stack S )
  55. {
  56.         // 确保S不为空栈
  57.         assert( !IsEmpty( S ) );

  58.         return S->Next->Element;
  59. }

  60. void Pop( Stack S )
  61. {
  62.         PtrToNode FirstCell;

  63.         // 确保S不为空栈
  64.         assert( !IsEmpty( S ) );

  65.         FirstCell = S->Next;
  66.         S->Next = FirstCell->Next;
  67.         free( FirstCell );
  68. }

  69. ElementType TopAndPop( Stack S )
  70. {
  71.         PtrToNode FirstCell;
  72.         ElementType X;

  73.         // 确保S不为空栈
  74.         assert( !IsEmpty( S ) );

  75.         FirstCell = S->Next;
  76.         X = FirstCell->Element;
  77.         S->Next = FirstCell->Next;
  78.         free( FirstCell );

  79.         return X;
  80. }
复制代码
  1. // TestStack.c
  2. #include "Stack.h"
  3. #include <stdio.h>

  4. int main()
  5. {
  6.         Stack S = NULL;

  7.         S = CreateStack();

  8.         Push( 520, S );
  9.         Push( 1314, S );

  10.         while( !IsEmpty(S) )
  11.                 printf( "出栈元素是: %d\n", TopAndPop(S) );

  12.         return 0;
  13. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-4-19 18:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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