从一个对象实例看数据抽象与封装

来源:互联网 发布:网络课程 知乎 编辑:程序博客网 时间:2024/05/20 04:12

本章目标:1、用C的方式实现栈2、用C++数据抽象的方式实现栈  3、比较两者的差异性

栈的插入用头插法,这样子访问最快

不采用头节点。

C代码:

#include<stdio.h>#include<stdlib.h>#include<assert.h>//定义栈中的元素struct Link{int data;struct Link* next;};//定义一个栈结构体//只需要头指针(没有头结点)//还有结构体的大小维护struct Stack{struct Link* head;int size;};void StackInit(struct Stack* stack){stack->head = NULL;stack->size = 0;}void StackPush(struct Stack* stack,const int data){struct Link* node;node = (struct Link*)malloc(sizeof(struct Link));assert(node != NULL);node->data = data;//node->next = stack->head->next;error并不给头指针分配空间node->next = stack->head;stack->head = node;++stack->size;}int StackEmpty(struct Stack* stack){return (stack->size == 0);}int StackPop(struct Stack* stack,int *data){if(StackEmpty(stack)){return 0;}struct Link* tmp = stack->head;*data = stack->head->data;stack->head = stack->head->next;free(tmp);--stack->size;return 1;}void StackCleanup(struct Stack* stack){struct Link* tmp;while(stack->head){tmp = stack->head;stack->head = stack->head->next;free(tmp);}stack->size = 0;}int main(){struct Stack stack;StackInit(&stack);int i = 0;for(i = 0;i < 5;i++){StackPush(&stack,i);}while(!StackEmpty(&stack)){StackPop(&stack,&i);printf("%d ",i);}printf("\n");return 0;}

头结点的作用是使所有链表(包括空表)的头指针非空,并使对单链表的插入、删除操作不需要区分是否为空表或是否在第一个位置进行,从而与其他位置的插入、删除操作一致。 同时头结点的数据域可以存储尾节点的地址。

栈的插入是没必要用头结点的,因为每一步插入都一样

但是删除不能这样,要判断是否为空,如果是有头结点就没有必要,但是这个影响不是很大


C++代码:

#include <iostream>using namespace std;class Stack{//结构体也是类struct Link{int data_;struct Link* next_;Link(int data,Link *next):data_(data),next_(next){}};public://c++中会把0作为空指针的Stack():head_(0),size_(0){}void Push(const int data){Link *node = new Link(data,head_); head_ = node;++size_;}bool Pop(int& data){if(Empty()){return false;}Link *tmp = head_;data = head_->data_;head_ = head_->next_;delete tmp;--size_;return true;}bool Empty(){return (size_ == 0);}~Stack(){Link *tmp;while(head_){tmp = head_;head_ = head_->next_;delete tmp;}size_ = 0;}private:Link *head_;int size_;};int main(void){Stack stack;        // 抽象数据类型  类类型    int i;    for (i=0; i<5; i++)    {        //StackPush(&stack, i);        stack.Push(i);      // this = &stack    }     //while (!StackEmpty(&stack))    while (!stack.Empty())    {        //StackPop(&stack, &i);        //printf("%d ", i);        stack.Pop(i);        cout<<i<<" ";    }    //printf("\n");    cout<<endl;     return 0;}


对比:
1、栈的构造与删除不一样的

2、增加删除的方法不一样,写起来更加自然

3、用类的方式来实现,可以避免名称冲突,因为C无法保证别人写的代码和自身不一样,而C++写的代码在类的作用域之中,不容易产生名称冲突的问题,而且在C++中,也可以用namespace A{}这样子的书写规范


4、类型的扩充,比如类类型Stack stack和int a很像

5、数据封装,能够保护内部的数据结构不遭受外部的破坏,比如说Head_






0 0
原创粉丝点击