TPS1H000AQDGNRQ1参数规格:40V/1A/HVSSOP-8/汽车级高侧开关详解
2026/9/12 2:52:01
#pragmaonce#include<stdio.h>#include<assert.h>#include<stdlib.h>#include<stdbool.h>// 实现带头的单链表(头结点可以看做第0个结点,因为它的数据域不存储有效数据)// 定义单链表的结点typedefintElemType;typedefstructLNode{//每个结点中存储一个数据,以及下一个结点的地址ElemType data;structLNode*next;}LNode,*LinkList;// 将struct LNode重命名为LNode,将struct LNode*重命名为LinkList// 单链表的初始化boolListInit(LinkList&L);// L是头结点的地址的别名,L的值变了,头结点的地址也就变了// 将数据域为e的新结点插到第i个存储有效数据的位置(i>=1且i<=原链表中有效结点个数+1)boolListInsert(LinkList&L,inti,ElemType e);// i=原链表中有效结点个数+1时,表示把新结点插在链表的尾部// 本项目实现的是带头的单链表,插入新结点时,头结点的地址不会变化,因此这里的形参可以不加&// 但如果实现的是不带头的单链表,这里的形参必须加&// 后插操作:在p指向的结点后插入数据域为e的新结点boolInsertNextNode(LNode*p,ElemType e);// 前插操作:在p指向的结点之前插入数据域为e的新结点boolInsertPriorNode(LNode*p,ElemType e);// 如果形参部分给了头结点的地址,则可以从头结点遍历到p指向的结点的前一个结点,再插入新结点// 删除第i个存储有效数据的结点,并把该结点中数据域的值赋值给变量eboolListDelete(LinkList&L,inti,ElemType&e);// 本项目实现的是带头结点的单链表,删除存储有效数据的结点时,头结点的地址不会变化,因此这里的形参也可以不加&// 但如果实现的是不带头结点的单链表,这里的形参必须加&// 删除p指向的结点boolDeleteNode(LNode*p);// 若形参部分给了头结点的地址,可以从头结点遍历到p指向的结点的前一个结点,再删除p指向的结点。时间复杂度为O(n)// 若形参的部分没有给头结点的地址,则可以通过“偷天换日”的操作,从逻辑上删除该结点,时间复杂度为O(1)// 虽然通过“偷天换日”的操作使得时间复杂度降低了,但是这种方式不能删除尾结点,程序会报错// 查找第i个存储实际数据的结点,若找到了就返回该结点的地址,否则返回NULLLNode*GetElem(LinkList L,inti);// L接收头结点的地址// 按值查找:查找有效结点中,第一个数据域的值为e的结点,如果找到了就返回该结点的地址,没找到就返回NULLLNode*LocateElem(LinkList L,ElemType e);// 求单链表的长度(即有效结点的个数)intLength(LinkList L);#define_CRT_SECURE_NO_WARNINGS1#include"SList.h"// 单链表的初始化boolListInit(LinkList&L)// L是头结点的地址的别名(也就是test函数中plist的别名),L的值变了,头结点的地址也就变了{// 申请头结点的空间L=(LNode*)malloc(sizeof(LNode));// L接收头结点的地址if(L==NULL)// L = NULL时表示头结点的空间申请失败returnfalse;L->next=NULL;returntrue;}// 将数据域为e的新结点插到第i个存储有效数据的位置(i>=1且i<=原链表中有效结点个数+1)// i=原链表中有效结点个数+1时,表示把新结点插在链表的尾部boolListInsert(LinkList&L,inti,ElemType e){// 本项目实现的是带头的单链表,插入新结点时,头结点的地址不会变化,因此这里的形参可以不加&// 但如果实现的是不带头的单链表,这里的形参必须加&if(i<1)returnfalse;// 先找到第i-1个存储有效数据的结点,再将新结点查到它后面intj=0;LNode*p=L;while(p!=NULL&&j<i-1)// j从0变化到i-2,循环i-1次{p=p->next;j++;}if(p==NULL)// 当p=NULL时,说明i的值不合法,说明此时i>原链表中有效结点的个数+1returnfalse;//此时p指向第i-1个存储有效数据的结点// 申请新结点的空间LNode*s=(LNode*)malloc(sizeof(LNode));if(s==NULL)// 如果新结点的空间申请失败returnfalse;s->data=e;s->next=p->next;p->next=s;returntrue;}// 后插操作:在p指向的结点后插入数据域为e的新结点boolInsertNextNode(LNode*p,ElemType e){if(p==NULL)returnfalse;// 表示插入失败// 插入新结点前,申请新结点的空间LNode*s=(LNode*)malloc(sizeof(LNode));if(s==NULL)returnfalse;//表示新结点的空间申请失败s->data=e;s->next=p->next;p->next=s;returntrue;}// 前插操作:在p指向的结点之前插入数据域为e的新结点boolInsertPriorNode(LNode*p,ElemType e){if(p==NULL)returnfalse;//说明p指向的是无效结点,插入失败// 申请新结点的空间LNode*s=(LNode*)malloc(sizeof(LNode));if(s==NULL)// 如果新结点的空间申请失败returnfalse;// 先将新结点插入到p指向的结点后面,再交换这两个结点中数据域的值,实现偷天换日的效果s->next=p->next;p->next=s;s->data=p->data;p->data=e;returntrue;}// 删除第i个存储有效数据的结点,并把该结点中数据域的值赋值给变量eboolListDelete(LinkList&L,inti,ElemType&e){if(i<1)returnfalse;// 先找到第i-1个存储有效数据的结点,再删除第i个结点LNode*p=L;// p此时指向头结点intj=0;while(p!=NULL&&j<i-1)// j从0增加到i-2,循环i-1次{p=p->next;j++;}if(p==NULL)// 当p==NULL时,说明i>原链表中有效结点的个数,i的值不合法returnfalse;if(p->next==NULL)// 当p->next=NULL时,说明p指向尾结点,需要删除尾结点后面的结点,显然是非法行为returnfalse;// 此时p指向第i-1个存储有效数据的结点LNode*dele=p->next;//dele指向需要删除的结点e=dele->data;// 将需要删除的结点中数据域的值赋给变量e,并修改该函数调用时实参(m)的值p->next=dele->next;free(dele);// 释放需要删除的结点的空间dele=NULL;returntrue;}// 删除p指向的结点(该代码不能删除尾结点,否则会导致对空指针解引用)boolDeleteNode(LNode*p){if(p==NULL)returnfalse;// 若p指向的是无效结点,则返回NULLLNode*q=p->next;// q指向待删除结点的后面一个结点// 先将q指向的结点中数据域的值赋给p指向的结点,再删除q指向的结点。// 这种操作在逻辑上等价于删除p指向的结点p->data=q->data;p->next=q->next;free(q);// 释放q指向的结点的空间q=NULL;returntrue;}// 查找第i个存储实际数据的结点,若找到了就返回该结点的地址,否则返回NULLLNode*GetElem(LinkList L,inti)// L接收头结点的地址{if(i<0)// 比如i=-1时,表示查找第-1个存储实际数据的结点,显然是非法操作,返回NULLreturnNULL;LNode*p=L;// p此时指向头结点,若要找到第i个存储有效数据的结点,需要向后遍历i次intj=0;while(p!=NULL&&j<i)// j从0增加到i-1,循环i次{p=p->next;j++;}returnp;/* 补充1:当i=0时,表示查找第头结点,因为头结点后面的结点才是第1个存储有效数据的结点 此时while循环会循环0次,最后返回头结点的地址 补充2:当i>链表中有效结点的个数时,p最终会等于NULL,直接退出while循环,返回p,即返回NULL */}// 按值查找:查找有效结点中,第一个数据域的值为e的结点,如果找到了就返回该结点的地址,没找到就返回NULLLNode*LocateElem(LinkList L,ElemType e){LNode*p=L->next;// p指向第一个存储有效数据的结点while(p!=NULL&&p->data!=e)p=p->next;returnp;// 若找到该结点就返回该结点的地址,否则返回NULL}// 求单链表的长度(即有效结点的个数)intLength(LinkList L){LNode*p=L;// p此时指向头结点intcount=0;while(p->next!=NULL){p=p->next;count++;}returncount;}#define_CRT_SECURE_NO_WARNINGS1#include"SList.h"voidTest(){// 创建一个空的带头单链表(即一个头结点)LNode*plist=NULL;// plist是头指针,指向头结点// 测试单链表的初始化ListInit(plist);// 分别插入数据域的值为1、2、3的结点 即头结点->1->2->3for(inti=1;i<=3;i++){ListInsert(plist,i,i);}// 删除第2个存储有效数据的结点ElemType m;ListDelete(plist,2,m);printf("删除的结点中存储的数据是%d\n",m);// 求单链表的长度(即有效结点的个数)printf("单链表的长度为:%d",Length(plist));}intmain(){Test();return0;}