Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1048684
  • 博文数量: 573
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-28 16:21
文章分类

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: C/C++

2015-12-02 14:55:54


点击(此处)折叠或打开

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. #define NAMELEN 32
  5. #define    ADDRLEN 128

  6. /*单链表的虚拟实现*/
  7. typedef struct lnode
  8. {
  9.     char name[NAMELEN];
  10.     char addr[ADDRLEN];
  11.     char sex;
  12.     float score;
  13.     int id;
  14.     struct lnode * next;
  15. }NODE;

  16. typedef NODE * NodePtr;

  17. int Initlist(NodePtr * headptr);
  18. int CreatNode(NodePtr * nodeptr, char * name, char * addr, char sex, float score, int id);
  19. int Lenlist(NodePtr headptr);
  20. int GetNode(NodePtr headptr, int num, NodePtr * nodeptr);
  21. int AddNode(NodePtr headptr, NodePtr nodeptr);
  22. int PrintAllNode(NodePtr headptr);
  23. int InsertNode(NodePtr headptr, int num, NodePtr nodeptr);
  24. int DeleteNode(NodePtr headptr, int num);
  25. int UnionList(NodePtr headptr1, NodePtr headptr2);
  26. int SortNode(NodePtr headptr);
  27. int SortNode2(NodePtr headptr);

  28. int main(int argc, char ** argv)
  29. {
  30.     printf("*********单向非循环链表的操作********\n");
  31.     
  32.     NodePtr headptr = NULL;
  33.     Initlist(&headptr); /*需传指针的地址,才能改变指针变量的值*/
  34.     
  35.     NodePtr nodeptr = NULL;
  36.     CreatNode(&nodeptr, "wxc", "hb", 'm', 100.00, 1);
  37.     AddNode(headptr, nodeptr);
  38.     CreatNode(&nodeptr, "zqp", "hb", 'w', 100.00, 2);
  39.     AddNode(headptr, nodeptr);
  40.     CreatNode(&nodeptr, "程序员", "上海", 'm', 100.00, 3);
  41.     AddNode(headptr, nodeptr);
  42.     CreatNode(&nodeptr, "wolp", "上海", 'w', 100.00, 4);
  43.     AddNode(headptr, nodeptr);
  44.     CreatNode(&nodeptr, "wxc", "上海", 'm', 99.00, 6);
  45.     AddNode(headptr, nodeptr);
  46.     PrintAllNode(headptr);
  47.     
  48.     NodePtr getnodeptr = NULL;
  49.     int num = 3;
  50.     GetNode(headptr, num, &getnodeptr);
  51.     printf("*************取得第[%d]个元素如下:************\n", num);
  52.     printf(" id =[%d]\n name =[%s]\n addr =[%s]\n sex =[%c]\n score=[%.2f]\n", getnodeptr->id, getnodeptr->name, getnodeptr->addr, getnodeptr->sex, getnodeptr->score);

  53.     CreatNode(&nodeptr, "wo", "上海", 'm', 98.00, 5);
  54.     num = 6;
  55.     InsertNode(headptr, num, nodeptr);
  56.     /*
  57.     num = 4;
  58.     DeleteNode(headptr, num);
  59.     */
  60.     PrintAllNode(headptr);
  61.     
  62.     NodePtr headptr2 = NULL;
  63.     Initlist(&headptr2); /*需传指针的地址,才能改变指针变量的值*/
  64.     
  65.     NodePtr nodeptr2 = NULL;
  66.     CreatNode(&nodeptr2, "wxc", "hb", 'm', 98.00, 13);
  67.     AddNode(headptr2, nodeptr2);
  68.     CreatNode(&nodeptr2, "zqp", "hb", 'w', 99.00, 12);
  69.     AddNode(headptr2, nodeptr2);
  70.     CreatNode(&nodeptr2, "程序员", "上海", 'm', 100.00, 11);
  71.     AddNode(headptr2, nodeptr2);
  72.     
  73.     UnionList(headptr, headptr2);
  74.     PrintAllNode(headptr);
  75.     
  76.     SortNode(headptr);
  77.     PrintAllNode(headptr);
  78.     
  79.     SortNode2(headptr);
  80.     PrintAllNode(headptr);
  81.     printf("链表长度=[%d]\n", Lenlist(headptr));
  82.     
  83.     return 0;
  84. }

  85. /*
  86. 单链表面试题:
  87. 写一个函数将一个链表逆序.
  88. 单链表,不知道长度,写一个函数快速找到中间节点的位置.
  89. 写一个函数找出一个单向链表的倒数第n个节点的指针
  90. */

  91. /*功能:初始化单链表:(带头结点的)初始时链表为空*/
  92. int Initlist(NodePtr * headptr)
  93. {
  94.     printf("初始化链表......\n");
  95.     *headptr = (NodePtr)malloc(sizeof(NODE)); /*头结点*/
  96.     (*headptr)->next = NULL;
  97.     return 0;
  98. }

  99. /*创建一个节点*/
  100. int CreatNode(NodePtr * nodeptr, char * name, char * addr, char sex, float score, int id)
  101. {
  102.     *nodeptr = (NodePtr)malloc(sizeof(NODE));
  103.     memset((*nodeptr)->name, 0, sizeof(char)*NAMELEN);
  104.     strcpy((*nodeptr)->name, name);
  105.     memset((*nodeptr)->addr, 0, sizeof(char)*ADDRLEN);
  106.     strcpy((*nodeptr)->addr, addr);
  107.     (*nodeptr)->sex = sex;
  108.     (*nodeptr)->score = score;
  109.     (*nodeptr)->id = id;
  110.     (*nodeptr)->next = NULL;
  111.     return 0;
  112. }

  113. /*功能:求单链表的长度,参数node:头结点指针*/
  114. int Lenlist(NodePtr headptr)
  115. {
  116.     int len = 0;
  117.     NodePtr p = NULL;
  118.     p = headptr->next;
  119.     while(p != NULL)
  120.     {
  121.         len++;
  122.         p = p->next;
  123.     }
  124.     return len;
  125. }

  126. /*功能:求单链表中的第num个元素的节点指针*/
  127. int GetNode(NodePtr headptr, int num, NodePtr * nodeptr)
  128. {
  129.     NodePtr p = NULL;
  130.     int count = 1;
  131.     if(num < 0)
  132.     {
  133.         printf("num值不可小于0!\n");
  134.         return -1;
  135.     }
  136.     if(num == 0)
  137.     {
  138.         *nodeptr = headptr;
  139.         return 0;
  140.     }
  141.     p = headptr->next;
  142.     while((p != NULL)&&(count < num))
  143.     {
  144.         p = p->next;
  145.         count++;
  146.     }
  147.     if((p == NULL)||(count < num)) /*第num个元素不存在*/
  148.     {
  149.         printf("count = [%d]\n", count);
  150.         printf("第[%d]个元素不存在!\n", num);
  151.         return -1;
  152.     }
  153.     else if((p != NULL)&&(count == num)) /*第num个元素存在*/
  154.         {
  155.             *nodeptr = p;
  156.             return 0;
  157.         }
  158. }

  159. /*功能:在单链表尾插入一个元素*/
  160. int AddNode(NodePtr headptr, NodePtr nodeptr)
  161. {
  162.     printf("在链尾增加一个元素!\n");
  163.     NodePtr p = NULL;
  164.     
  165.     p = headptr;
  166.     while(p->next != NULL) /*p指向最后一个节点元素了*/
  167.     {
  168.         p = p->next;
  169.     }
  170.     p->next = nodeptr;
  171.     return 0;
  172. }

  173. /*功能:打印出单链表中所有节点元素的信息*/
  174. int PrintAllNode(NodePtr headptr)
  175. {
  176.     NodePtr p = NULL;
  177.     p = headptr->next;
  178.     printf("链表长度=[%d]\n", Lenlist(headptr));
  179.     printf("显示链表的所有内容如下:\n");
  180.     printf("*************************************************************************\n");
  181.     printf("id        name        addr        sex        score\n");
  182.     while(p != NULL)
  183.     {
  184.         printf("[%d]        [%s]    [%s]        [%c]        [%.2f]\n", p->id, p->name, p->addr, p->sex, p->score);
  185.         p = p->next;
  186.     }
  187.     return 0;
  188. }

  189. /*功能:在单链表的第num个元素之前插入一个元素(先找到第num-1个元素)*/
  190. int InsertNode(NodePtr headptr, int num, NodePtr nodeptr)
  191. {
  192.     int count = 1;
  193.     NodePtr p = NULL;
  194.     p = headptr->next;
  195.     while((p != NULL)&&(count < num-1)) /*p会指向第num-1个元素*/
  196.     {
  197.         count++;    
  198.         p = p->next;
  199.     }
  200.     if((p != NULL)&&(num-1 == 0))/*在第1个元素之前插入新的元素*/
  201.     {
  202.         nodeptr->next = headptr->next;
  203.         headptr->next = nodeptr;
  204.         return 0;
  205.     }
  206.     else if((p == NULL)||(count > num-1)) /*第num-1个元素不存在*/
  207.     {
  208.         printf("第[%d]个元素不存在!\n", num-1);
  209.         return -1;
  210.     }
  211.     else if((p != NULL)&&(count == num-1)) /*p指向第num-1个元素*/
  212.     {
  213.         nodeptr->next = p->next;
  214.         p->next = nodeptr;
  215.         return 0;
  216.     }
  217.     
  218.     return 0;
  219. }

  220. /*功能:删除单链表中的第num个元素*/
  221. int DeleteNode(NodePtr headptr, int num)
  222. {
  223.     NodePtr p = NULL;
  224.     NodePtr q = NULL;
  225.     int count = 1;
  226.     
  227.     p=headptr->next;
  228.     while((p != NULL)&&(count < num-1)) /*p会指向第num-1个元素*/
  229.     {
  230.         count++;    
  231.         p = p->next;
  232.     }
  233.     if((p != NULL)&&(num-1 == 0))/*要删除的是第1个元素*/
  234.     {
  235.         q = headptr->next;
  236.         headptr->next = headptr->next->next;
  237.         free(q); /*删除的节点要释放*/
  238.         return 0;
  239.     }
  240.     else if((p == NULL)||(count > num-1)) /*第num-1个元素不存在*/
  241.     {
  242.         printf("第[%d]个元素不存在!\n", num-1);
  243.         return -1;
  244.     }
  245.     else if((p != NULL)&&(count == num-1)) /*p指向第num-1个元素*/
  246.     {
  247.         q = p->next;
  248.         p->next = q->next;
  249.         free(q); /*删除的节点要释放*/
  250.         return 0;
  251.     }
  252.     
  253.     return 0;
  254. }

  255. /*功能:按照数据域中某个数据成员的值(id)对单链表的元素进行递增排序*/
  256. int SortNode(NodePtr headptr)
  257. {
  258.     int i, j, len;
  259.     NodePtr P0 = NULL;
  260.     NodePtr P1 = NULL;
  261.     NodePtr P2 = NULL;
  262.     
  263.     printf("对单链表排序如下:\n");
  264.     len = Lenlist(headptr);
  265.     /*用冒泡法排序:相邻两数比较,对链表来说,交换相邻两数要相对容易的多*/
  266.     for(i=0; i<len-1; i++)
  267.     {
  268.         for(j=0; j<len-1-i; j++)
  269.         {
  270.             GetNode(headptr, j, &P0); /*j=0,则P0是头指针*/
  271.             P1 = P0->next;
  272.             P2 = P0->next->next;
  273.             /*P1,P2是要交换的2个节点的指针,P0是这2个节点之前的节点指针*/
  274.             /*3个节点的指针都已经保存,所以就不需要另外定义临时节点指针了*/
  275.             if(P1->id > P2->id)
  276.             {
  277.                 P1->next = P2->next;
  278.                 P2->next = P1;
  279.                 P0->next = P2;
  280.             }
  281.         }
  282.     }
  283.     
  284.     return 0;
  285. }

  286. /*功能:按照数据域中某个数据成员的值(id)对单链表的元素进行递减排序*/
  287. int SortNode2(NodePtr headptr)
  288. {
  289.     int i, j, len;
  290.     NodePtr p0 = NULL;
  291.     NodePtr p1 = NULL;
  292.     NodePtr p2 = NULL;
  293.     
  294.     printf("对单链表排序如下:\n");
  295.     len = Lenlist(headptr);
  296.     /*用冒泡法排序:相邻两数比较,对链表来说,交换相邻两数要相对容易的多*/
  297.     for(i=0; i<len-1; i++)
  298.     {
  299.         p0 = headptr; /*p0指向头节点*/
  300.         for(j=0; j<len-1-i; j++)
  301.         {
  302.             p1 = p0->next;
  303.             p2 = p0->next->next;
  304.             /*p1,p2是要交换的2个节点的指针,p0是这2个节点之前的节点指针*/
  305.             /*3个节点的指针都已经保存,p2->next的链不要断了,
  306.             也可以定义4个节点的指针,就绝对不会断链了*/
  307.             if(p1->id < p2->id)
  308.             {
  309.                 p1->next = p2->next;
  310.                 p2->next = p1;
  311.                 p0->next = p2;
  312.             }
  313.             p0 = p0->next; /*第一个最小的已经排好,所以p0可以指向下一个节点了*/
  314.         }
  315.     }
  316.     
  317.     return 0;
  318. }

  319. /*功能:合并2条单链表为1条链表(不排序)(还可以做让2条已经有序的链表归并为1条有序的链表???)*/
  320. int UnionList(NodePtr headptr1, NodePtr headptr2)
  321. {
  322.     NodePtr p1 = NULL;
  323.     
  324.     p1 = headptr1;
  325.     while(p1->next != NULL)/*p指向最后一个节点元素了*/
  326.     {
  327.         p1 = p1->next;
  328.     }
  329.     p1->next = headptr2->next; /*首尾连接2条链表*/
  330.     free(headptr2); /*第2条链表的头节点要释放*/
  331.     return 0;
  332. }

  333. /***********************************************************
  334. 把链表节点倒过来不是排序 英文试卷 我不认识那个递归的单词 第一遍是用非递归搞的
  335. 后来面试的时候当面写个递归的
  336. ************************************************************/

阅读(582) | 评论(0) | 转发(0) |
0

上一篇:任意数制的转换

下一篇:单循环链表

给主人留下些什么吧!~~