链表由一系列不必在内存中相连的节点组成,分为单链,双链和循环链表。

根据链表的存储特点可以得出链表的特点:可以快捷的进行插入和删除操作,但是查找操作费时。

主要复习下单链表。已c实现单链表的insert,delete等操作。

链表C语言实现:

//单链
struct listNode
{
 int data;
 listNode* next;
};
//在链表position位置前插入节点。
int insert(listNode *root,int value,int position)
{
 listNode *p,*s;
 p = root;
 int j = 1;
 while(p&&j<position)
 {
  p = p->next;
  ++j;
 }
 if(p==NULL|| j>position)
 {
  return -1;
 }
 //s = (listNode*)new(listNode);
 s = (listNode*)malloc(sizeof(*root));
 if(s==NULL)
 {
  return -1;
 }
 s->data = value;
 s->next = p->next;
 p->next = s;
 return 1;
}
//删除position位置的元素,并由value返回其值
int deleteNode(listNode *root,int position,int &value)
{
 int j = 1;
 listNode *p,*q;
 p=root;
 while(p&&j<position)
 {
  p = p->next;
  ++j;
 }
 if((p->next)==NULL||j>position)
 {
  return -1;
 }
 q = p->next;
 p->next =q->next;
 value = q->data;
 free(q);
 return 1;
}

//删除给定的节点
void deleteNode(listNode *node)
{
 assert(node != NULL);
 listNode * nxt = node->next;
 if(nxt != NULL)
 {
  node->data = nxt->data;
  node->next = nxt->next;
  delete nxt;
  return;
 }
 delete node;
}

//单链表反转
listNode* RevlistNode(listNode * root)
{
 if(root == NULL)
 {
  return NULL;
 }
 if(root->next == NULL)
 {
  return root;
 }
 listNode *cur,*pre,*nxt;
 pre= NULL;
 cur = root;
 while(cur)
 {
  nxt = cur->next;
  cur->next = pre;
  pre = cur;
  cur=nxt;
 }
 return pre;
}

 

 

1.单链表反转。

以微软的一道面试题为例,编写一个函数,给定一个链表的头指针,要求只遍历一次,将单链表中的元素顺序反转过来。

给出反转函数:

 

Node* LinkList_reverse(Node* head) 
{ 
    Node *preNode,*curNode,*nextNode; 
  
    if(head==NULL) return NULL;//空链表 
  
    if(head->next == NULL) return head;//仅一个元素 
  
    curNode = head;preNode=NULL;//初始化 
  
    while(curNode) 
    { 
        nextNode = curNode->next;//先记录下一个结点 
        curNode->next = preNode;//改变链表方向(逆置) 
        preNode = curNode;//将当前结点作为下一次循环的前一个结点 
        curNode = nextNode;//向后推移一个结点 
    } 
  
    return preNode;//当遍历完链表后curNode应该为空,此时preNode链表头(head) 
} 

2.链表添加节点

//在给定的节点前插入新节点
void LinkList_Add(Node* ptr,Node* newNode)
{
    int temp = 0;
    newNode->next = ptr->next;
    ptr->next = newNode;
    temp = ptr->e;
    ptr->e = newNode->e;
    newNode->e = temp;
}

3.无头链表删除给定节点

同样以一面试题为例

假设一个没有头指针的单链表,一个指针指向此单链表中间的一个节点(非第一个或最后一个节点),请将该节点删除。

//删除节点
void LinkList_Delete(Node* ptr)
{
    Node* temp = ptr->next;
    if(temp != NULL)
    {
    ptr->e = temp->e;
    ptr->next = temp->next;
    delete temp;//这里delete好像有问题,以后再看下
    }
}