关于单链表的一些小结

链表算是C语言中比较重要一个知识点了,之前学习时粗略的学过链表,这次回过头来回顾一下

首先是链表的前置知识结构体和指针,链表就是一个结构体内有一个指向本类型的指针,这样一个一个串起来形成逻辑上的连续存储.

(里面有少许c++语法,可以自行替换成c语法)





#define Sfault 0
#define Strue  1


typedef char NodeDataC;
typedef int  NodeDataI;
typedef struct NodeLink
{
    NodeDataC *name;
NodeDataI id;
struct NodeLink * next;
}Node;


//头插法
int Head_insert(Node * h,NodeDataI Serial_number, NodeDataC * pszname)
{
    Node * node = (Node*)malloc(sizeof(Node)/sizeof(char));
if(node == NULL)
return Sfault;
node->name = pszname;
node->id   = Serial_number;
    
node->next = h->next;
h->next    = node;
    return Strue;
}


//遍历链表,打印数据
int Traverse_Link(Node* h)
{
Node* tmp = h->next;
while(tmp)
{
         cout << tmp->id << "  " << tmp->name << endl; 
         tmp  = tmp->next;
}
return Strue;
    
}


//尾插法
int Tail_insert(Node* h,NodeDataI Serial_number, NodeDataC * pszname)
{
    Node* node = (Node*)malloc(sizeof(Node)/sizeof(char));
if(node == NULL)
return Sfault;
node->next = NULL;


    Node* tmp = h;
while(tmp->next)
{
tmp   = tmp->next;
}
node->id  = Serial_number;
node->name = pszname;
tmp->next = node;
return Strue;
}


//删除第pos个结点
int Delete_pos(Node* h,int pos)
{
    Node* tmp = h;
for(int i = 0;i < pos - 1;i++)
{
if(tmp->next != NULL)
{
tmp = tmp->next;
}
}
Node* p = tmp->next;
tmp->next = p->next;
free(p);
return Strue;
}


//链表逆序
int Reverse_List(Node* h)
{
Node* pre = h->next;
Node* cur = h->next->next;
Node* tmp;
while(cur)
{
        tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
h->next->next = NULL;
h->next = pre;
return Strue;
}


int main()
{
Node * h = (Node *)malloc(sizeof(Node)/sizeof(char));
h->next = NULL;
        Head_insert(h,3,"xin");
Head_insert(h,2,"jia");
        Head_insert(h,1,"li");
        Tail_insert(h,4,"ni");
        Tail_insert(h,5,"hao");
Tail_insert(h,6,"a");
        // Delete_pos( h,4);
        Traverse_Link(h);
        Reverse_List(h);
Traverse_Link(h);
return 0;
}

这里讲下思路

首先是头插法思路:(头插法是最简单的插入方法,不过头插法插入的数据是反的)

①先malloc一个节点空间,判断是否成功

②向新节点写入数据,注意新节点node->next = h->next

③h->next=node

尾插法思路:

①先malloc一个节点空间判断是否成功

②创一个结构体指针Node*tmp=h,当tmp->next存在时tmp=tmp->next(一步一步将tmp向后移直到tmp->next=NULL)

③向新节点写入数据.注意,由于是尾插法,所以node->next=NULL

④tmp->next=node

删除第pos个结点思路:

①创建一个结构体指针tmp指向h,用来指向要删除位置的前一个结点

②循环向后移寻找结点,直到pos-1的位置

③创建一个结构体指针p指向tmp->next,这时p就是要删除的第pos个结点

④tmp->next=p->next

⑤free(p)

链表逆序思路:

①判断传进来的链表是否有两个以上的结点(如果节点数小于两个,就没必要逆序)

②创建三个结构体指针pre,cur,tmp,   pre=h->next,cur= h->next->next

③判断cur的存在,即当cur不为NULL时,可以进入循环 tmp =cur->next,就算cur是链表的最后一个节点也无所谓,这时cur->next=NULL及tmp=NULL

④逆序 cur->next=pre

⑤循环后移交换三个变量pre=cur,cur=tmp

⑥将逆序前的第一个节点的next指向NULL,h->next->next=NULL

⑦将h指向pre,h->next=pre

逆序图示:


猜你喜欢

转载自blog.csdn.net/qq_37059136/article/details/80817829