《程序员面试宝典》-数据结构编程练习1

本文介绍了一个简单的单链表程序,包括链表的创建、长度测量、元素打印、节点删除与插入等功能,并尝试实现了链表的逆置操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序包含:单链表的建立,测长,打印,删除节点,插入节点以及逆置

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #define ok 1
  6 #define error 0
  7 
  8 typedef struct Node
  9 {
 10     int data;
 11     struct Node *next;
 12 }Node;
 13 typedef struct Node *LinkList;
 14 
 15 //建立链表
 16 void CreatListTail(LinkList *L,int n)
 17 {
 18     LinkList p,r;//不加星号
 19     int i=0,x;
 20     *L=(LinkList)malloc(sizeof(Node));
 21     r=*L;//r是L的尾节点
 22     printf("input %d numbers(1~99) to creat a linklist\n",n);
 23     while(i<n)
 24     {
 25         scanf("%d",&x);
 26         if(x>1&&x<99)
 27         {
 28             p=(LinkList)malloc(sizeof(LinkList));//循环中每个节点都应该新生成
 29             p->data=x;
 30             r->next=p;
 31             r=p;
 32             i++;
 33         }
 34         else
 35         {
 36             printf("illega number ,please input a number between 1 and 99.\n");
 37             fflush(stdin);//清空键盘输入流缓冲区,防止死循环(当输入字母时会进入死循环),不完美,仅对第一位输入字母有效
 38         }
 39     }
 40     printf("OK\n");
 41     r->next=NULL;
 42 }
 43 
 44 //显示链表
 45 void ListTraverse(LinkList L)
 46 {
 47     int i=0;
 48     LinkList p=L->next;//指向第一个节点
 49     while(p)
 50     {
 51         printf("%d   ",p->data);
 52         p=p->next;
 53         i++;
 54     }
 55     printf("\n Linklist contain %d Nodes",i);
 56 }
 57 
 58 //删除链表元素
 59 int ListDelete(LinkList L,int j,int *e)
 60 {
 61     LinkList p=L,q;
 62     int i=1;
 63     while(p->next && i<j)
 64     {
 65         p = p->next;
 66         i++;
 67     }
 68     if(!(p->next)||i>j)
 69     return error;
 70     q=p->next;
 71     p->next=q->next;
 72     *e = q->data;
 73     free(q);
 74     q=NULL;//free之后,内存释放,但指针仍指向内存位置
 75     printf("字符串变更为: \n");
 76     ListTraverse(L);
 77     return ok;
 78 }
 79 
 80 //将节点插入链表
 81 int ListInsert(LinkList L,int i, int e)
 82 {
 83     int j=1;
 84     LinkList p,s;
 85     p=L;//注意循环次数
 86     while(p && j<i)
 87     {
 88         p=p->next;
 89         j++;
 90     }
 91     if(!p || j>i)
 92     return error;
 93     s=(LinkList)malloc(sizeof(Node));
 94     s->data=e;
 95     s->next=p->next;
 96     p->next=s;
 97     return ok;
 98 }
 99 
100 //逆序链表(使用递归) 待修改总是报错
101 LinkList *ListRever(LinkList *L)
102 {
103     LinkList p,Node,Next,HeadNode;
104     p=*L;//头结点
105     if(p==NULL)
106         return NULL;//链表操作要有安全检查,头结点不为空
107     if(p->next==NULL)
108         return p;//递归的结束点,即为逆序后的头结点,函数的返回值HeadNode
109     Node = p;
110     Next = p->next;
111     HeadNode = ListRever(Next);
112     Next->next = Node;//逆置
113     Node->next = NULL;//防止产生循环列表
114     return HeadNode;
115 }
116 //1.用递归算法,对于不带头结点的单链表(a1,a2,a3,a4,a5,a6)逆置后的结果为(a6,a5,a4,a3,a2,a1)
117 //考虑递归算法,若只有一个结点,则直接返回,若存在两个结点(a1,a2)则需要做的操作有:a2->next=a1;a1->next=NULL;return a2;
118 //a2即新的头结点,若有三个结点,则应先将子链(a2,a3)先逆置且返回该子链的新的头结点,然后把子链(a2,a3)当作一个复合结点a2'
119 //from(http://blog.sina.com.cn/s/blog_4d7c6fd50100y0ql.html)
120 
121 
122 int main()
123 {
124     int n=1,e,j;
125     LinkList L;
126     printf("input n \n");
127     scanf("%d",&n);
128     CreatListTail(&L, n);//采用&L:函数中是引用型的,这里将地址传递
129     ListTraverse(L);//显示字符串和长度
130     
131     printf("\n 删除第?个元素 \n");
132     scanf("%d",&j);
133     ListDelete(L,j,&e);//删除第i个元素,并显示剩余链表
134 
135     printf("\n 在第3个位置前插入e=3 \n");
136     ListInsert(L,3,3);
137     ListTraverse(L);
138     
139     ListRever(&L);
140     printf("逆置后 \n");
141     ListTraverse(L);
142 
143 
144     
145 }

 

转载于:https://www.cnblogs.com/richard-meng/p/4687722.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值