数据结构基础之单链表
对单链表的建立,插入,删除,逆序,打印元素做一个小小的总结,不过我不觉得这些东西在具体的工作后到底能发挥什么作用,因为强大的STL已经把这些都做好了,我们只需要明白在什么场合使用哪一个STL就可以了。链表有一个数据域,有一个指针域,它的操作其实就是对指针域的操作,无非是指来指去而已。也许这些能反映出一个人的思维敏捷度,以及扎实的编程基础吧。 但是我想说的是这些玩意在你头脑比较清楚的时候写这个很简单,但是当你烦躁的时候,不好写吧,除非你经常写这个。单链表看着简单,但是不见得能写的正确。 该代码经过验证,测试正确,但是代码中不免有错误之处,或者哪些部分写的不好,希望高手能指出来,不胜感激。因为代码必须经过验证,那些没有经过验证的代码是不负责任的代码。在代码中我加了详细的注释。 - #include
- #include
- #include
- using namespace std;
- typedef struct NODE_STRU
- {
- int data;//数据域
- struct NODE_STRU *next;//指针域
- }NODE;
- //创建单链表
- NODE *Create()
- {
- NODE *head, *p, *s;//head表示头结点,p表示当前节点,s表示添加的新节点
- int input_data;
- int cycle_flag = 1;
- head = (NODE*)malloc(sizeof(NODE));//首先为头结点分配空间
- p = head;//当前节点指向头结点
- while(cycle_flag)
- {
- cout << "please input data(if input 0, cycle over!):"<< endl;
- cin >> input_data;
- if(0 != input_data)
- {
- s = (NODE*)malloc(sizeof(NODE));//为新添加的数据分配节点空间
- s->data = input_data;
- p->next = s;//当前节点的下一个节点指向新节点
- p = s;//将当前节点指向新节点
- }
- else
- {
- cycle_flag = 0;
- }
- }
- head = head->next;//由于头结点没有数据,使头结点指向下一个节点,即指向第一个真正的节点
- p->next = NULL;//数据插入完成后,当前节点也跑到了最后,使它的下一个节点置为NULL,表示节点完成
- return head;
- }
- //单链表测长,这个很简单,只需判断当前节点(初始化当前节点为头结点)是不是为空,如果不为空指向下一个节点,并计数就可以了
- int Length(NODE *head)
- {
- int length = 0;
- NODE *p = head;
- while(p != NULL)
- {
- p = p->next;
- length++;
- }
- return length;
- }
- //打印单链表,这个也很简单,在当前节点(初始化当前节点为头结点)不为空时候,打印出来,并使得当前节点指向下一个节点即可
- void Print(NODE *head)
- {
- NODE *p = head;
- int length = Length(head);
- cout << "link length is: " << length << endl;
- while(p != NULL)
- {
- cout << "data: " << p->data << " ";
- p = p->next;
- }
- }
- //删除节点,这里的删除节点是根据节点数据进行删除的,不是从第一个节点进行删除,也不是从最后一个节点进行删除
- //p->next = p->next->next
- NODE *Del(NODE *head, int num)
- {
- NODE *p1, *p2;//p1表示当前节点,初始化时指向头结点
- p1 = head;
- while(num != p1->data && p1->next != NULL)//如果当前节点的数据域与要删除的数据不相等,使当前节点指向下一个节点
- {
- p2 = p1;//在未找到节点时指针指向下一个节点前,先保存该节点
- p1 = p1->next;
- }
- if(num == p1->data)//如果当前节点数据域与要删除的数据相等
- {
- if(p1 == head)//如果当前节点为头结点,将头结点指向当前节点的下一个节点,并释放当前节点
- {
- head = p1->next;
- free(p1);
- }
- else//如果当前节点为中间节点,使当前节点指向下一个节点,注意:这里不能使用p1->next=p1->next->next,使用之前保存的节点
- p2->next = p1->next;
- }
- else
- cout << num << "can not find in link!" << endl;
- return head;
- }
- //插入节点,在这里只在链表的结尾进行插入
- NODE *Insert(NODE *head, int num)
- {
- NODE *p0, *p1, *p2;//p0表示新插入的节点,p1表示当前节点,初始化的时候指向头结点,p2用于保存当前节点
- p1 = head;
- p0 = (NODE *)malloc(sizeof(NODE));
- p0->data = num;
- while(p1->next != NULL)//如果当前节点的下一个节点不为空,当前节点指向下一个节点,这样当前节点最后为最后一个节点
- {
- p2 = p1;
- p1 = p1->next;
- }
- p1->next = p0;
- p0->next = NULL;
- return head;
- }
- //进行排序,其实就是简单的冒泡排序,时间复杂度为O(n2),空间复杂度为O(1),稳定
- NODE *Sort(NODE *head)
- {
- NODE *p;
- if(head == NULL || head->next == NULL)
- return head;
- int length = Length(head);//得到链表的长度,用于遍历
- for(int i=1; i<length; i++)
- {
- p = head;
- for(int j=0; j<length-i; j++)
- {
- if(p->data > p->next->data)
- {
- int temp = p->data;
- p->data = p->next->data;
- p->next->data = temp;
- }
- p = p->next;
- }
- }
- return head;
- }
- //链表逆序
- NODE *Reverse(NODE *head)
- {
- if(head == NULL || head->next == NULL)
- return head;
- //这样来实现,在链表中一次从链表尾删除节点,然后在新建立的链表中插入节点(尾插法)
- int length = Length(head);
- int a[length];
- int i = 0;
- NODE *p = head;
- while(p != NULL)
- {
- a[i] = p->data;
- i++;
- p = p->next;
- }
- for(int j=0; j<length; j++)="" 暂时用于测试
- cout << j << ":" << a[j]<<"";
- NODE *newhead, *link, *s;
- newhead = (NODE *)malloc(sizeof(NODE));
- link = newhead;
- for(int k=length-1; k>=0; k--)
- {
- s = (NODE *)malloc(sizeof(NODE));
- s->data = a[k];
- link->next = s;
- link = s;
- }
- newhead = newhead->next;
- link->next = NULL;
- return newhead;
- }
- //求单链表的中间节点
- void SearchMid(NODE* head)
- {
- cout << "head data: " << head->data<< "";
- NODE *tmp1 = head;
- NODE *tmp2 = head;
- NODE *mid;
- while(tmp1->next != NULL && tmp1->next->next != NULL)
- {
- tmp1 = tmp1->next->next;
- tmp2 = tmp2->next;
- cout << "tmp1:" << tmp1->data<< ",tmp2:" << tmp2->data<<"";
- }
- mid = tmp2;
- cout << "SearchMid mid data: " << mid->data;
- }
- int main(int argc, char *argv[])
- {
- cout << "create link..." << endl;
- NODE *p = Create();
- cout << "print link..." << endl;
- Print(p);
- int delnode;
- cout << "input delete node: ";
- cin >> delnode;
- cout << "delete node " << delnode << endl;
- Del(p, delnode);
- cout << "print link..." << endl;
- Print(p);
- cout << "insert link...";
- Insert(p, 20);
- Print(p);
- cout <<"sort from low to high...";
- Sort(p);
- Print(p);
- cout << "reverse...";
- NODE *revlink = Reverse(p);
- Print(revlink);
- cout << "find mid node data...";
- SearchMid(p);
- return 0;
- }
复制代码运行结果:
数据结构基础之单链表
摘自:http://blog.csdn.net/feitianxuxue/article/details/9989591 |