作者:Bryant Lei
出处:http://blog.csdn.net/bryantlei
1.实现双链表的反转。
解析:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* prior;
struct node* next;
}node, *DLinkList;
/*
//头插法建立带头结点的双链表
DLinkList createDLinkList()
{
int i;
node *head,*cur,*end;//head是头结点,end指向链表的最后一个结点
head = (node*)malloc(sizeof(node));
head->next = NULL;
head->prior = NULL;
end = head;
while((scanf("%d",&i)) != EOF)
{
cur = (node *)malloc(sizeof(node));
cur->data = i;
cur->prior = end;
end->next = cur;
end = cur;
}
end->next = NULL;
return head;
}
*/
//头插法建立不带头结点的双链表
DLinkList createDLinkList()
{
int i;
node *head=NULL,*cur,*end;//head是第一个结点,end指向链表的最后一个结点
while((scanf("%d",&i)) != EOF)
{
if(head == NULL)
{
head = (node*)malloc(sizeof(node));
head->data = i;
head->next = NULL;
head->prior = NULL;
end = head;
}
else
{
cur = (node *)malloc(sizeof(node));
cur->data = i;
cur->prior = end;
end->next = cur;
end = cur;
}
}
end->next = NULL;
return head;
}
//反转双链表
DLinkList reverseDLinkList(DLinkList head)
{
DLinkList pReverseHead = NULL;//反转后的第一个结点
DLinkList pNode = head;//正在被反转的结点
DLinkList pre = NULL;//正在被反转的结点的前一个结点
if(!head)
return NULL;
while(pNode != NULL)
{
DLinkList pNext = pNode->next;//记录正在被反转的结点的下一个结点
if(pNext == NULL)
pReverseHead = pNode;
pNode->next = pre;
if(pre)//如果正在处理的结点不是第一个结点
pre->prior = pNode;
pre = pNode;
pNode = pNext;
}
pReverseHead->prior = NULL;
return pReverseHead;
}
//利用双链表的pre指针从后到前打印不带头结点的双链表(这样做可以测试双链表是否正确建立)
void printDLinkList(DLinkList dList)
{
while(dList && dList->next)
{
dList = dList->next;
}
while(dList)
{
printf("%d ",dList->data);
dList = dList->prior;
}
}
int main()
{
DLinkList list;
list = createDLinkList();
printDLinkList(list);
printf("\n");
list = reverseDLinkList(list);
printDLinkList(list);
return 0;
}
注解:关于struct和typedef struct的详细说明可以参考:
http://blog.csdn.net/whkjlcw/article/details/23381739
2.如何在const成员函数中修改成员变量的值?
解析:在C++中,由const修饰的成员函数的函数体内部,是不能够对成员变量进行修改的。这个特性被用来保证某些成员函数在实现过程中,避免由于程序员大意而对数据进行了错误的修改;同时也说明此成员函数是非修改性的。如只需要返回成员变量的成员函数就被声明为const类型(const的位置在函数定义参数列表之后)
推广开来,在const成员函数中也不能够调用非const的成员函数。这是因为非const成员函数可能会改变成员变量的值,这与const成员函数的定义相违背。
但是在某些情况下,需要在const函数中改变成员变量。这就需要把成员变量设置成mutable类型。如
class C
{
public:
void func(const int&p) const
{
i = p;
}
private:
mutable int i;
};
如果变量i不声明为mutable类型,则编译不会通过。
如果成员变量是一个类类型或者结构类型,而在const函数中调用这些变量的成员函数,除了用mutable声明外,还可以用一种变通的方法:
class D
{
public:
void op(){}
}
class C
{
public:
void func(const int&p, D& d) const
{
i = p;
d.op();
}
private:
mutable int i;
D cd;
};
然后在调用时,参数D& d以*this作为输入,也可以达到调用非const函数的作用。
P.S 最近阅读相关的文章,又学到了一种方法,能够使得在const成员函数中调用非const成员函数。就是使用const_cast<>运算符。它能够使得const去掉const的属性,使得violate属性去掉violate属性。上面的例子就可以写成。
void func() const
{
const_cast<D*>(&cd)->op();
}
同样能够编译通过。
Result: 笔试通过,本来是要一面的,但是面试官一听到我的实习时间最多3个月(这个公司要求10个月以上),马上就说:“我们这个面试没必要进行,因为公司硬性要求实习时间必须是10个月以上,抱歉!”于是,面试就木有啦。。