链表虽然感觉定义还算懂。。但是感觉每次装配起来都得各种查资料。。这次准备记录下来,以便以后查阅,也请路过的大牛指点有什么错误。
首先是转配node,
typedef struct node{
char character;
node* next;
} node;
值为character,然后指向下一个node。
然后装配linked list class,
/* List class */
class linkedlist {
public:
linkedlist(); /* constructor */
~linkedlist(); /* destructor */
void insertAtBack(char character); /* helper function */
bool remove(char character); /* helper function */
bool isEmpty();
void print(); /* print the linked list */
private:
node* head; /* head pointer */
node* tail; /* tail pointer */
};
有默认的构造函数,析构函数,在后面插入node,根据值remove node。(这主要因为list自带的remove是将所有的含有该值的node全部删除,故准备自己做个链表类,用来测试cracking the coding interview上的题)。另外两个就是比较简单的测试是否是empty,以及打印该链表所有元素。。
首先先是构造函数,和析构函数。。其实我这里概念挺晕的。。。由于半路出家,且用的时间不算太久。。。
/* default constructor */
linkedlist::linkedlist() { head = NULL; tail = NULL;}
/* destructor */
linkedlist::~linkedlist() {
if (!isEmpty()) { /* linkedlist is not empty */
cout << "Destroying nodes..." << endl;
node* current = head; /* current node */
node* temp; /* temp node */
while (current != NULL) { /* deleteing remaining node */
temp = current;
cout << temp->character << endl;
current = current->next;
delete temp;
} /* end while */
} /* end if */
cout << "All nodes destroyed!" << endl;
}
我用析构函数在结束类调用之后,将链表占用内存删除。。
然后是最简单的isEmpty()函数,就是检查head指针是否指向NULL,如果是,则为空。
bool linkedlist::isEmpty() {
return head == NULL;
}
然后是insertAtBack(char)
void linkedlist::insertAtBack(char character) {
node* newNode = new node();
newNode->character = character;
newNode->next = NULL;
if (isEmpty())
head = tail = newNode ; /* new list has only one node */
else {
tail->next = newNode;
tail = newNode;
} /* end else */
}
如果为空,则new一个node。。然后头指针,尾指针都指向该node。
如果其中有元素。则插入到尾指针的后面,在把尾指针指向该node.。
然后是比较复杂的remove函数。。
/* delete a node from the list */
bool linkedlist::remove(char character) {
/* create a temp node */
node* temp = head;
node* prev;
if (isEmpty()) /* no node */
return false;
else if (temp->next == NULL) {
delete temp;
head = NULL;
tail = NULL;
return true;
}
else if (temp->character == character) { /* delete the fisrt node */
head = temp->next;
delete temp;
}
else { /* comman case */
node* prev;
/* find the node */
while (temp->character != character && temp->next != NULL) {
prev = temp;
temp = temp->next;
}
/* if find the node */
if (temp->character == character && temp->next != NULL) {
prev->next = temp->next;
delete temp;
return true;
}
else if (temp->character == character && temp->next == NULL) {
/* find the last node */
prev->next = NULL;
delete temp;
return true;
}
else
return false;
}
}
1.如果为空,返回false;
2.如果只有1个node,且不是要找的,则不做任何处理,返回false
3.如果第一个node就是要删除的,则head指针指向下一个,返回true
4. Comman case
寻找node(如果首指针是要找的或者只有唯一node,则不会进入常规搜索,故将这两种情况提到前面去)。
4.1 若找到node,且不是尾node,剔除current node,prev node指向 current->next
4.2 若找到node,且是尾node,prev->next指向空,删除current node
4.3 没找到,返回 false
这些case我设计的不太好,路过大神可以给点建议。。。我只是用了下我脑子里最直接的想法。。可能里面有错,我在使用中发现,会直接去更新!
最后就是print()了。。
/* display contents of linkedlist */
void linkedlist::print() {
if (isEmpty())
cout << "This linked list is empty!" << endl;
node* current = head;
cout << "The linked list is: ";
while (current != NULL) {
cout << current->character << ' ';
current = current->next;
}
cout << endl;
}
测试函数:
运行没有问题,我就不上传运行结果了,大家可以去测试下,看看哪些case不符合。。
int main(int argc, char **argv) {
linkedlist testlist;
testlist.insertAtBack('F');
testlist.insertAtBack('O');
testlist.insertAtBack('L');
testlist.insertAtBack('L');
testlist.insertAtBack('O');
testlist.insertAtBack('W');
testlist.insertAtBack(' ');
testlist.insertAtBack('U');
testlist.insertAtBack('P');
testlist.remove('O');
return 0;
}
本博客只是想记录一下我做的一些工作,并非是真正的技术博客。。。本学渣乃是一介菜鸟,会犯所有菜鸟都会犯的错误。。请各位指正。。
另外上传下本程序的链接:https://github.com/YimengL/CTCI-cpp/blob/master/linkedlist.cpp